/**
 * Get more info at : www.jrebirth.org .
 * Copyright JRebirth.org © 2011-2013
 * Contact : sebastien.bordes@jrebirth.org
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.jrebirth.af.core.resource.builder;

import java.lang.ref.WeakReference;
import java.util.Map;
import java.util.WeakHashMap;

import org.jrebirth.af.api.resource.ResourceItem;
import org.jrebirth.af.api.resource.ResourceParams;
import org.jrebirth.af.api.resource.builder.ResourceBuilder;
import org.jrebirth.af.core.resource.Resources;
import org.jrebirth.af.core.resource.provided.JRebirthParameters;

/**
 * The abstract class <strong>AbstractResourceBuilder</strong>.
 *
 * The base abstract class used to manage resource weakly.
 *
 * @author Sébastien Bordes
 *
 * @param <I> The item used to wrap the resource
 * @param <P> The resource params type
 * @param <R> The real resource managed
 */
public abstract class AbstractResourceBuilder<I extends ResourceItem<?, ?, ?>, P extends ResourceParams, R> implements ResourceBuilder<I, P, R> {

    /** The resource weak Map. */
    private final Map<I, P> paramsMap = new WeakHashMap<I, P>();

    /** The resource weak Map. */
    private final Map<String, WeakReference<R>> resourceMap = new WeakHashMap<>();

    /**
     * {@inheritDoc}
     */
    @Override
    public void storeParams(final I key, final P params) {
        // Store the resource into the map
        this.paramsMap.put(key, params);

        // Activate the AutoRefresh feature only for other parameters
        if (Resources.isNotAutoRefreshParam(params) && JRebirthParameters.AUTO_REFRESH_RESOURCE.get()) {
            params.activateAutoRefresh();
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public P getParam(final I key) {
        // Retrieve the resource from the map
        return this.paramsMap.get(key);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String getParamKey(final I key) {
        return getParam(key).getKey();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public R get(final I key) {

        final P params = getParam(key);

        final String paramsKey = params.getKey();

        // Retrieve the resource into the map
        WeakReference<R> resource = this.resourceMap.get(paramsKey);

        // The resource may be null if nobody use it
        if (resource == null || resource.get() == null) {
            // So we must rebuild an instance and then store it weakly
            set(paramsKey, buildResource(key, params));

            // Get the WeakReference
            resource = this.resourceMap.get(paramsKey);

            params.hasChanged(false);
        }
        return resource.get();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void set(final String key, final R resource) {
        this.resourceMap.put(key, new WeakReference<R>(resource));
    }

    /**
     * Build the resource requested.
     *
     * @param item the parameter item used to identify the resource element
     * @param params the primitive parameters used to build the resource
     *
     * @return the resource built and weakly stored with a WeakReference
     */
    protected abstract R buildResource(final I item, final P params);

}

@@ -2799,36 +2799,51 @@
 ve the resource 
-into
+weak reference from
  the map%0D%0A      
@@ -2861,32 +2861,39 @@
 ence%3CR%3E resource
+WeakRef
  = this.resource
@@ -2938,16 +2938,23 @@
 resource
+WeakRef
  may be 
@@ -2984,20 +2984,18 @@
         
-if (
+R 
 resource
@@ -3000,17 +3000,41 @@
 ce =
+ resourceWeakRef =
 = null 
-%7C%7C
+? null :
  res
@@ -3038,22 +3038,79 @@
 resource
-.get()
+WeakRef.get();%0D%0A        if (resourceWeakRef == null %7C%7C resource
  == null
@@ -3202,22 +3202,18 @@
     
-set(paramsKey,
+resource =
  bui
@@ -3235,20 +3235,17 @@
  params)
-);%0D%0A
+;
 %0D%0A      
@@ -3254,91 +3254,33 @@
     
-// Get the WeakReference%0D%0A            resource = this.resourceMap.get(paramsKey);%0D%0A
+set(paramsKey, resource);
 %0D%0A  
@@ -3350,22 +3350,16 @@
 resource
-.get()
 ;%0D%0A    %7D

Fix ResourceBuilder where resources could be garbage collected before getting it