Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright 2009-2013 Tilmann Zaeschke. All rights reserved.
*
* This file is part of ZooDB.
*
* ZooDB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* ZooDB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with ZooDB. If not, see .
*
* See the README and COPYING files for further information.
*/
package org.zoodb.jdo.internal.util;
import java.util.HashMap;
import java.util.Map;
import javax.jdo.JDOHelper;
import javax.jdo.PersistenceManager;
import javax.jdo.Transaction;
import org.zoodb.api.impl.ZooPCImpl;
import org.zoodb.jdo.PersistenceManagerImpl;
import org.zoodb.jdo.TransactionImpl;
/**
* This class serves as a replacement for transient fields in persistent classes that
* can not be allowed to be garbage collected. It provides transient
* behavior for a static field. Instances of this class must
* always be referenced via the static modifier (see example below).
* It needs to be static because transient is not
* reliable (see below) and because it can't be 'normal' (persistent).
*
* In cases, where the data can not be regenerated, this class
* can be used to store transient attributes safely for the lifetime
* of the Java VM.
*
* The example below shows hot to use the TransientField class.
*
*
* class Example {
*   //A transient field of type "String"
*   private final static TransientField<String> _tempName =
* new TransientField<String>("default name");
*   private final static TransientField<Boolean> _tempBool =
* new TransientField(true);
*   private final static TransientField<Number> _tempNumber =
* new TransientField<Number>();
*  
*   public String getTempName() {
*     return _tempName.get(this);
*   }
*  
*   public void setTempName(String name) {
*     _tempName.set(this, name);
*   }
*  
*   public boolean getTempBoolean() {
*     return _tempBool.get(this);
*   }
*  
*   public void setTempBoolean(boolean b) {
*     _tempBool.set(this, b);
*   }
*  
*   public void setTempLong(Long l) {
*     _tempNumber.set(this, l);
*   }
*  
*   public void setTempDouble(Double d) {
*     _tempNumber.set(this, d);
*   }
*  
*   public void finalize() {
*     try {
*       _tempName.cleanIfTransient(this);
*       _tempBool.cleanIfTransient(this);
*       _tempNumber.cleanIfTransient(this);
*     } finally {
*       super.finalize();
*     }
* }
*
*
* This class is optimized to reference as few owners as possible. It stores
* owner/value pairs only if the value differs from the default value. If a
* value is set to the default value, then the owner/value pair is removed.
*
* This class does not require the owner nor the value to be persistent class.
*
* Each TransientField has a type and a value. The type is
* defined via generics <T> in the declaration. The default
* value can be set via the constructor, otherwise it is null.
*
* Internally in this class, persistent objects are identified via their OID,
* transient (all not persistent) objects are identified via their identity in
* the Java VM. This means persistent objects are unique with respect to their
* ObjectStore, whereas non-persistent objects are shared across the whole Java
* VM.
* E.g. instances of an persistent Object X can be loaded in different Stores.
* The Java VM treats them as separate objects, and they do not share their
* values in the transient fields managed by TransientField.
*
* The implementation of this class is not very performant due to the way the
* ObjectStore is accessed.
*
* Garbage Collection
* To allow garbage collection of the values and the owner, please set the
* values to their default (method 1) or call the cleanup method (method 2).
* E.g.:
*
* class Example {
*   private final static TransientField _tempName =
* new TransientField<String>();//default = null
*  
*   public void allowGarbageCollectionLaternative1() {
*     _tempName.set(this, null);
*   }
*  
*   public void allowGarbageCollectionAlternative2() {
*     _tempName.deregisterOwner(this);
*  
*   public void finalize() {
*     try {
*       _tempName.cleanIfTransient(this);
*     } finally {
*       super.finalize();
*     }
*   }
* }
*
* Otherwise neither the owner nor the value can be garbage collected.
*
* @author Tilmann Zaeschke
* @param Type of the fields value.
*/
public class TransientField {
//A list of all Transient fields
private static final Map, Object> _allFields =
new WeakIdentityHashMap, Object>();
//A map to have one OidMap per Transaction.
//Each OidMap maps all instances to their transient value.
//Note that the PersitenceManager may never be garbage collected as long as
//it is in this list. This is because the persistent objects in the OidMap
//appear to have a hard reference to the PersistenceManager.
//We make the map 'weak' anyway.
private final Map> _txMap =
new WeakIdentityHashMap>();
//have a field to avoid garbage collection
private final OidMap