Home » apache-openjpa-1.1.0-source » org.apache.openjpa » 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.meta;
   20   
   21   import org.apache.openjpa.lib.util.Localizer;
   22   import org.apache.openjpa.util.MetaDataException;
   23   import org.apache.openjpa.util.UserException;
   24   
   25   /**
   26    * Default {@link ValueMetaData} implementation.
   27    *
   28    * @author Abe White
   29    * @nojavadoc
   30    */
   31   public class ValueMetaDataImpl
   32       implements ValueMetaData {
   33   
   34       private static final Localizer _loc = Localizer.forPackage
   35           (ValueMetaDataImpl.class);
   36   
   37       ///////////////////////////////////////////////////////////////
   38       // Note: if you add additional state that should be copied to
   39       // embedded metadata, make sure to add it to the copy() method
   40       ///////////////////////////////////////////////////////////////
   41   
   42       private FieldMetaData _owner;
   43       private Class _decType = Object.class;
   44       private int _decCode = JavaTypes.OBJECT;
   45       private ClassMetaData _decTypeMeta = null;
   46       private Class _type = null;
   47       private int _code = JavaTypes.OBJECT;
   48       private ClassMetaData _typeMeta = null;
   49       private Class _typeOverride = null;
   50       private int _delete = CASCADE_NONE;
   51       private int _persist = CASCADE_AUTO;
   52       private int _attach = CASCADE_IMMEDIATE;
   53       private int _refresh = CASCADE_AUTO;
   54       private boolean _serialized = false;
   55       private Boolean _embedded = null;
   56       private ClassMetaData _embeddedMeta = null;
   57       private int _resMode = MODE_NONE;
   58       private String _mappedBy = null;
   59       private FieldMetaData _mappedByMeta = null;
   60   
   61       protected ValueMetaDataImpl(FieldMetaData owner) {
   62           _owner = owner;
   63       }
   64       
   65       /**
   66        * Constructor for serialization.
   67        */
   68       protected ValueMetaDataImpl() {
   69       }
   70   
   71       public FieldMetaData getFieldMetaData() {
   72           return _owner;
   73       }
   74   
   75       public MetaDataRepository getRepository() {
   76           return _owner.getRepository();
   77       }
   78   
   79       public Class getType() {
   80           return (_type == null) ? _decType : _type;
   81       }
   82   
   83       public void setType(Class type) {
   84           _type = type;
   85           _typeMeta = null;
   86           if (type != null)
   87               setTypeCode(JavaTypes.getTypeCode(type));
   88       }
   89   
   90       public int getTypeCode() {
   91           return (_type == null) ? _decCode : _code;
   92       }
   93   
   94       public void setTypeCode(int code) {
   95           _code = code;
   96       }
   97   
   98       public boolean isTypePC() {
   99           return getTypeCode() == JavaTypes.PC
  100               || getTypeCode() == JavaTypes.PC_UNTYPED;
  101       }
  102   
  103       public ClassMetaData getTypeMetaData() {
  104           if (_type == null)
  105               return getDeclaredTypeMetaData();
  106           if (_typeMeta == null && _code == JavaTypes.PC) {
  107               ClassMetaData meta = _owner.getDefiningMetaData();
  108               _typeMeta = meta.getRepository().getMetaData(_type,
  109                   meta.getEnvClassLoader(), true);
  110           }
  111           return _typeMeta;
  112       }
  113   
  114       public Class getDeclaredType() {
  115           return _decType;
  116       }
  117   
  118       public void setDeclaredType(Class type) {
  119           _decType = type;
  120           _decTypeMeta = null;
  121           _decCode = JavaTypes.getTypeCode(type);
  122           if (_embeddedMeta != null)
  123               _embeddedMeta.setDescribedType(type);
  124       }
  125   
  126       public int getDeclaredTypeCode() {
  127           return _decCode;
  128       }
  129   
  130       public void setDeclaredTypeCode(int code) {
  131           _decCode = code;
  132       }
  133   
  134       public boolean isDeclaredTypePC() {
  135           return _decCode == JavaTypes.PC || _decCode == JavaTypes.PC_UNTYPED;
  136       }
  137   
  138       public ClassMetaData getDeclaredTypeMetaData() {
  139           if (_decTypeMeta == null && _decCode == JavaTypes.PC) {
  140               if (isEmbedded())
  141                   _decTypeMeta = getEmbeddedMetaData();
  142               else {
  143                   ClassMetaData meta = _owner.getDefiningMetaData();
  144                   _decTypeMeta = meta.getRepository().getMetaData(_decType,
  145                       meta.getEnvClassLoader(), true);
  146               }
  147           }
  148           return _decTypeMeta;
  149       }
  150   
  151       public boolean isEmbedded() {
  152           if (_owner.getManagement() != _owner.MANAGE_PERSISTENT)
  153               return false;
  154           if (_embedded == null) {
  155               // field left as default; embedded setting depends on type
  156               switch (_decCode) {
  157                   case JavaTypes.PC:
  158                   case JavaTypes.COLLECTION:
  159                   case JavaTypes.MAP:
  160                   case JavaTypes.PC_UNTYPED:
  161                       _embedded = Boolean.FALSE;
  162                       break;
  163                   default:
  164                       _embedded = Boolean.TRUE;
  165               }
  166           }
  167           return _embedded.booleanValue();
  168       }
  169   
  170       public void setEmbedded(boolean embedded) {
  171           if (embedded && _embedded != Boolean.TRUE) {
  172               _decTypeMeta = null;
  173               _typeMeta = null;
  174           }
  175           _embedded = (embedded) ? Boolean.TRUE : Boolean.FALSE;
  176       }
  177   
  178       public boolean isEmbeddedPC() {
  179           return _decCode == JavaTypes.PC && isEmbedded();
  180       }
  181   
  182       public ClassMetaData getEmbeddedMetaData() {
  183           if (_embeddedMeta == null && isEmbeddedPC())
  184               addEmbeddedMetaData();
  185           return _embeddedMeta;
  186       }
  187   
  188       public ClassMetaData addEmbeddedMetaData() {
  189           MetaDataRepository repos = _owner.getRepository();
  190           _embeddedMeta = repos.newEmbeddedClassMetaData(this);
  191           _embeddedMeta.setDescribedType(_decType);
  192           repos.getMetaDataFactory().getDefaults().populate(_embeddedMeta,
  193               ClassMetaData.ACCESS_UNKNOWN);
  194   
  195           setEmbedded(true);
  196           return _embeddedMeta;
  197       }
  198   
  199       public int getCascadeDelete() {
  200           if (_owner.getManagement() != FieldMetaData.MANAGE_PERSISTENT)
  201               return CASCADE_NONE;
  202           if (isEmbeddedPC())
  203               return CASCADE_IMMEDIATE;
  204   
  205           switch (_delete) {
  206               case CASCADE_NONE:
  207                   // if the user marks the owning field dependent and we 
  208                   // externalize to a pc type, then become dependent
  209                   if (this != _owner.getValue() && isTypePC()
  210                       && ((ValueMetaDataImpl) _owner.getValue())._delete
  211                       == CASCADE_AUTO)
  212                       return CASCADE_AUTO;
  213                   break;
  214               case CASCADE_AUTO:
  215                   if (isTypePC())
  216                       return CASCADE_AUTO;
  217                   break;
  218               case CASCADE_IMMEDIATE:
  219                   if (isDeclaredTypePC())
  220                       return CASCADE_IMMEDIATE;
  221                   break;
  222           }
  223           return CASCADE_NONE;
  224       }
  225   
  226       public void setCascadeDelete(int delete) {
  227           _delete = delete;
  228       }
  229   
  230       public int getCascadePersist() {
  231           if (_owner.getManagement() != FieldMetaData.MANAGE_PERSISTENT)
  232               return CASCADE_NONE;
  233           if (isDeclaredTypePC())
  234               return _persist;
  235           if (!isTypePC())
  236               return CASCADE_NONE;
  237           // if only externalized type is pc, can't cascade immediate
  238           return (_persist == CASCADE_IMMEDIATE) ? CASCADE_AUTO : _persist;
  239       }
  240   
  241       public void setCascadePersist(int persist) {
  242           _persist = persist;
  243       }
  244   
  245       public int getCascadeAttach() {
  246           if (_owner.getManagement() != FieldMetaData.MANAGE_PERSISTENT
  247               || !isDeclaredTypePC()) // attach acts on declared type
  248               return CASCADE_NONE;
  249           if (isEmbeddedPC())
  250               return CASCADE_IMMEDIATE;
  251           return _attach;
  252       }
  253   
  254       public void setCascadeAttach(int attach) {
  255           if (attach == CASCADE_AUTO)
  256               throw new IllegalArgumentException("CASCADE_AUTO");
  257           _attach = attach;
  258       }
  259   
  260       public int getCascadeRefresh() {
  261           if (_owner.getManagement() != FieldMetaData.MANAGE_PERSISTENT
  262               || !isDeclaredTypePC()) // refresh acts on declared type
  263               return CASCADE_NONE;
  264           return _refresh;
  265       }
  266   
  267       public void setCascadeRefresh(int refresh) {
  268           _refresh = refresh;
  269       }
  270   
  271       public boolean isSerialized() {
  272           return _serialized;
  273       }
  274   
  275       public void setSerialized(boolean serialized) {
  276           _serialized = serialized;
  277       }
  278   
  279       public String getValueMappedBy() {
  280           if (_mappedBy == MAPPED_BY_PK) {
  281               // use this instead of getting meta from element b/c that
  282               // requires element to be resolved
  283               ClassMetaData meta = getRepository().getMetaData
  284                   (_owner.getElement().getType(), null, false);
  285               if (meta == null)
  286                   throw new MetaDataException(_loc.get("val-not-pc", _owner));
  287               if (meta.getPrimaryKeyFields().length != 1)
  288                   throw new MetaDataException(_loc.get("val-not-one-pk",
  289                       _owner));
  290               _mappedByMeta = meta.getPrimaryKeyFields()[0];
  291               _mappedBy = _mappedByMeta.getName();
  292           }
  293           return _mappedBy;
  294       }
  295   
  296       public void setValueMappedBy(String mapped) {
  297           if (_owner.getKey() != this && mapped != null)
  298               throw new UserException(_loc.get("mapped-by-not-key", this));
  299           else {
  300               _mappedBy = mapped;
  301               _mappedByMeta = null;
  302           }
  303       }
  304   
  305       public FieldMetaData getValueMappedByMetaData() {
  306           if (getValueMappedBy() != null && _mappedByMeta == null) {
  307               ClassMetaData meta = _owner.getElement().getTypeMetaData();
  308               FieldMetaData field = (meta == null) ? null
  309                   : meta.getField(getValueMappedBy());
  310               if (field == null)
  311                   throw new MetaDataException(_loc.get("no-mapped-by", this,
  312                       getValueMappedBy()));
  313               if (field.getMappedBy() != null)
  314                   throw new MetaDataException(_loc.get("circ-mapped-by", this,
  315                       getValueMappedBy()));
  316               _mappedByMeta = field;
  317           }
  318           return _mappedByMeta;
  319       }
  320   
  321       public Class getTypeOverride() {
  322           return _typeOverride;
  323       }
  324   
  325       public void setTypeOverride(Class val) {
  326           _typeOverride = val;
  327       }
  328   
  329       public String toString() {
  330           String ret = _owner.getFullName(true);
  331           if (this == _owner.getKey())
  332               return ret + "<key:" + _decType + ">";
  333           if (this == _owner.getElement()) {
  334               if (_owner.getTypeCode() == JavaTypes.MAP)
  335                   return ret + "<value:" + _decType + ">";
  336               return ret + "<element:" + _decType + ">";
  337           }
  338           return ret + "<" + _decType + ">";
  339       }
  340   
  341       ////////////////////////
  342       // Resolve and validate
  343       ////////////////////////
  344   
  345       public int getResolve() {
  346           return _resMode;
  347       }
  348   
  349       public void setResolve(int mode) {
  350           _resMode = mode;
  351       }
  352   
  353       public void setResolve(int mode, boolean on) {
  354           if (mode == MODE_NONE)
  355               _resMode = mode;
  356           else if (on)
  357               _resMode |= mode;
  358           else
  359               _resMode &= ~mode;
  360       }
  361   
  362       public boolean resolve(int mode) {
  363           if ((_resMode & mode) == mode)
  364               return true;
  365           int cur = _resMode;
  366           _resMode |= mode;
  367   
  368           // we only perform actions for meta mode
  369           if ((mode & MODE_META) == 0 || (cur & MODE_META) != 0)
  370               return false;
  371   
  372           // check for type extension
  373           int codeOverride = JavaTypes.OBJECT;
  374           if (_typeOverride != null) {
  375               codeOverride = JavaTypes.getTypeCode(_typeOverride);
  376   
  377               // if there is no externalizer method or this value is a key or
  378               // element, set our type to the type extension; otherwise, use the
  379               // type extension as a hint to the actual type of the declared
  380               // value (e.g. marking an interface as non-pc)
  381               if (_owner.getExternalizerMethod() == null
  382                   || _owner.getValue() != this) {
  383                   _type = _typeOverride;
  384                   _code = codeOverride;
  385               } else {
  386                   _decCode = codeOverride;
  387                   if (JavaTypes.maybePC(codeOverride, _typeOverride))
  388                       resolveDeclaredType(_typeOverride);
  389               }
  390           }
  391   
  392           // see if actual type is pc
  393           if (JavaTypes.maybePC(_code, _type)) {
  394               _typeMeta = _owner.getRepository().getMetaData(_type,
  395                   _owner.getDefiningMetaData().getEnvClassLoader(), false);
  396               if (_typeMeta != null)
  397                   _code = JavaTypes.PC;
  398           }
  399   
  400           // if there is no externalizer, set our declared type code to the
  401           // actual type so that we treat the value correctly at runtime
  402           // (pers by reach, etc)
  403           if (_typeOverride != null && _owner.getExternalizerMethod() == null
  404               && _owner.getExternalValues() == null) {
  405               // cache the metadata immediately since we won't be able to get
  406               // it lazily, since we're not resetting _decType to _type
  407               _decCode = _code;
  408               _decTypeMeta = _typeMeta;
  409           } else if (JavaTypes.maybePC(_decCode, _decType))
  410               resolveDeclaredType(_decType);
  411   
  412           // resolves mapped by
  413           getValueMappedBy();
  414   
  415           ClassMetaData embed = getEmbeddedMetaData();
  416           if (embed != null)
  417               embed.resolve(MODE_META);
  418   
  419           // oid as primary key field?
  420           if (_decCode == JavaTypes.PC && isEmbedded()
  421               && _owner.isPrimaryKey() && _owner.getValue() == this)
  422               _code = _decCode = JavaTypes.OID;
  423   
  424           return false;
  425       }
  426   
  427       /**
  428        * Resolve the declared type.
  429        */
  430       private void resolveDeclaredType(Class type) {
  431           ClassMetaData meta = _owner.getRepository().getMetaData(type,
  432               _owner.getDefiningMetaData().getEnvClassLoader(), false);
  433           if (meta != null)
  434               _decCode = JavaTypes.PC;
  435           if (!isEmbedded())
  436               _decTypeMeta = meta;
  437       }
  438   
  439       public void copy(ValueMetaData vmd) {
  440           // copy declared types, but if OID revert to PC until we resolve
  441           // to OID ourselves
  442           _decType = vmd.getDeclaredType();
  443           _decCode = vmd.getDeclaredTypeCode();
  444           if (_decCode == JavaTypes.OID)
  445               _decCode = JavaTypes.PC;
  446   
  447           _delete = vmd.getCascadeDelete();
  448           _persist = vmd.getCascadePersist();
  449           _attach = vmd.getCascadeAttach();
  450           _refresh = vmd.getCascadeRefresh();
  451           _typeOverride = vmd.getTypeOverride();
  452           _serialized = vmd.isSerialized();
  453           if (_embeddedMeta != null)
  454               _embeddedMeta.setDescribedType(vmd.getDeclaredType());
  455   
  456           // don't allow copy to override embedded
  457           if (_embedded == null)
  458               setEmbedded(vmd.isEmbedded());
  459       }
  460   }

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