Home » apache-openjpa-1.1.0-source » org.apache.openjpa » datacache » [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.datacache;
   20   
   21   import java.util.BitSet;
   22   
   23   import org.apache.openjpa.kernel.AbstractPCData;
   24   import org.apache.openjpa.kernel.OpenJPAStateManager;
   25   import org.apache.openjpa.kernel.PCData;
   26   import org.apache.openjpa.kernel.PCDataImpl;
   27   import org.apache.openjpa.kernel.PCState;
   28   import org.apache.openjpa.kernel.StoreContext;
   29   import org.apache.openjpa.meta.ClassMetaData;
   30   import org.apache.openjpa.meta.FieldMetaData;
   31   import org.apache.openjpa.meta.JavaTypes;
   32   import org.apache.openjpa.meta.ValueMetaData;
   33   
   34   /**
   35    * Specialized {@link PCData} implementation for data caching. This
   36    * implementation is properly synchronized.
   37    *
   38    * @author Patrick Linskey
   39    */
   40   public class DataCachePCDataImpl
   41       extends PCDataImpl
   42       implements DataCachePCData {
   43   
   44       private final long _exp;
   45   
   46       /**
   47        * Constructor.
   48        */
   49       public DataCachePCDataImpl(Object oid, ClassMetaData meta) {
   50           super(oid, meta);
   51   
   52           int timeout = meta.getDataCacheTimeout();
   53           if (timeout > 0)
   54               _exp = System.currentTimeMillis() + timeout;
   55           else
   56               _exp = -1;
   57       }
   58   
   59       public boolean isTimedOut() {
   60           return _exp != -1 && _exp < System.currentTimeMillis();
   61       }
   62   
   63       public synchronized Object getData(int index) {
   64           return super.getData(index);
   65       }
   66   
   67       public synchronized void setData(int index, Object val) {
   68           super.setData(index, val);
   69       }
   70   
   71       public synchronized void clearData(int index) {
   72           super.clearData(index);
   73       }
   74   
   75       public synchronized Object getImplData() {
   76           return super.getImplData();
   77       }
   78   
   79       public synchronized void setImplData(Object val) {
   80           super.setImplData(val);
   81       }
   82   
   83       public synchronized Object getImplData(int index) {
   84           return super.getImplData(index);
   85       }
   86   
   87       public synchronized void setImplData(int index, Object val) {
   88           super.setImplData(index, val);
   89       }
   90   
   91       public synchronized Object getIntermediate(int index) {
   92           return super.getIntermediate(index);
   93       }
   94   
   95       public synchronized void setIntermediate(int index, Object val) {
   96           super.setIntermediate(index, val);
   97       }
   98   
   99       public synchronized boolean isLoaded(int index) {
  100           return super.isLoaded(index);
  101       }
  102   
  103       public synchronized void setLoaded(int index, boolean loaded) {
  104           super.setLoaded(index, loaded);
  105       }
  106   
  107       public synchronized Object getVersion() {
  108           return super.getVersion();
  109       }
  110   
  111       public synchronized void setVersion(Object version) {
  112           super.setVersion(version);
  113       }
  114   
  115       public synchronized void store(OpenJPAStateManager sm) {
  116           super.store(sm);
  117       }
  118   
  119       public synchronized void store(OpenJPAStateManager sm, BitSet fields) {
  120           super.store(sm, fields);
  121       }
  122   
  123       /**
  124        * Store field-level information from the given state manager.
  125        * Special process of checking if the cached collection data is out of order.
  126        */
  127       protected void storeField(OpenJPAStateManager sm, FieldMetaData fmd) {
  128           if (fmd.getManagement() != fmd.MANAGE_PERSISTENT)
  129               return;
  130           int index = fmd.getIndex();
  131   
  132           // if the field is a collection and has "order by" set, don't cache
  133           // it if this store is coming from a create or update (i.e., only
  134           // enlist in cache if this is coming from a database read).
  135           if (fmd.getOrders().length > 0) {
  136               if (sm.getPCState() == PCState.PNEW)
  137                   return;
  138               if (sm.getPCState() == PCState.PDIRTY) {
  139                   clearData(index);
  140                   return;
  141               }
  142           }
  143   
  144           super.storeField(sm, fmd);
  145   
  146           // If this field is used in "order by", we need to invalidate cache
  147           // for the collection that refer to this field.
  148           if ((sm.getPCState() == PCState.PDIRTY) && fmd.isUsedInOrderBy()) {
  149               clearInverseRelationCache(sm, fmd);
  150           }
  151       }
  152   
  153       /**
  154        * Check if this field is in use of "order by" by other field collections
  155        * in inverse relation. If it is, clear the other field cache because it
  156        * could be out of order.
  157        */
  158       protected void clearInverseRelationCache(OpenJPAStateManager sm,
  159           FieldMetaData fmd) {
  160           ClassMetaData cmd = sm.getMetaData();
  161           FieldMetaData[] fields = cmd.getFields();
  162           for (int i = 0; i < fields.length; i++) {
  163               FieldMetaData[] inverses = fields[i].getInverseMetaDatas();
  164               if (inverses.length == 0)
  165                   continue;
  166               for (int j = 0; j < inverses.length; j++) {
  167                   if (inverses[j].getOrderDeclaration()
  168                       .indexOf(fmd.getName()) != -1) {
  169                       DataCache cache = sm.getMetaData().getDataCache();
  170                       Object oid = sm.getContext().getObjectId(sm.fetch(i));
  171                       DataCachePCData data = cache == null ? null
  172                           : cache.get(oid);
  173                       if ((data != null) &&
  174                           (data instanceof DataCachePCDataImpl)) {
  175                           ((DataCachePCDataImpl) data)
  176                               .clearData(inverses[j].getIndex());
  177                       }
  178                   }
  179               }
  180           }
  181       }
  182   
  183       protected Object toData(FieldMetaData fmd, Object val, StoreContext ctx) {
  184           // avoid caching large result set fields
  185           if (fmd.isLRS() || fmd.isStream())
  186               return NULL;
  187           return super.toData(fmd, val, ctx);
  188       }
  189   
  190       protected Object toNestedData(ValueMetaData vmd, Object val,
  191           StoreContext ctx) {
  192           if (val == null)
  193               return null;
  194   
  195           // don't try to cache nested containers
  196           switch (vmd.getDeclaredTypeCode()) {
  197               case JavaTypes.COLLECTION:
  198               case JavaTypes.MAP:
  199               case JavaTypes.ARRAY:
  200                   return NULL;
  201               default:
  202                   return super.toNestedData(vmd, val, ctx);
  203           }
  204       }
  205   
  206       public AbstractPCData newEmbeddedPCData(OpenJPAStateManager sm) {
  207           return new DataCachePCDataImpl(sm.getId(), sm.getMetaData());
  208       }
  209   }

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