/*
 * Copyright 2015-2017 the original author or authors.
 *
 * 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.lastaflute.core.mail;

import java.util.Locale;

import org.dbflute.mail.Postcard;
import org.dbflute.mail.send.embedded.receptionist.SMailDynamicTextAssist;
import org.dbflute.optional.OptionalThing;
import org.lastaflute.core.magic.ThreadCacheContext;

/**
 * @since 0.6.0 (2015/05/16 Saturday)
 */
public abstract class LaThreadCachedDynamicTextAssist implements SMailDynamicTextAssist {

    protected static final Object NONE = new Object();

    @Override
    public String assist(Postcard postcard, String path, boolean filesystem, OptionalThing<Locale> receiverLocale) {
        final boolean exists = ThreadCacheContext.exists();
        final String cacheKey = exists ? generateCacheKey(path, filesystem, receiverLocale) : null;
        if (exists) {
            final String cached = ThreadCacheContext.getObject(cacheKey);
            if (cached != null) {
                return !cached.equals(NONE) ? cached : null;
            }
        }
        final String assisted = doAssist(postcard, path, filesystem, receiverLocale);
        if (exists) {
            if (assisted != null) {
                ThreadCacheContext.setObject(cacheKey, assisted);
                return ThreadCacheContext.getObject(cacheKey);
            } else {
                ThreadCacheContext.setObject(cacheKey, NONE); // also cache not-found
                return null;
            }
        } else {
            return assisted;
        }
    }

    protected String generateCacheKey(String path, boolean filesystem, OptionalThing<Locale> receiverLocale) {
        return "fw:mailText:" + path + ":" + filesystem + ":" + receiverLocale;
    }

    protected abstract String doAssist(Postcard postcard, String path, boolean filesystem, OptionalThing<Locale> receiverLocale);
}

@@ -699,24 +699,67 @@
 te.mail.
-Postcard
+send.embedded.receptionist.SMailDynamicDataResource
 ;%0Aimport
@@ -1069,186 +1069,704 @@
     
-protected static final Object NONE = new Object();%0A%0A    @Override%0A    public String assist(Postcard postcard, String path, boolean filesystem, OptionalThing%3CLocale%3E receiverLocal
+// ===================================================================================%0A    //                                                                          Definition%0A    //                                                                          ==========%0A    protected static final Object NONE = new Object();%0A%0A    // ===================================================================================%0A    //                                                                        Dynamic Data%0A    //                                                                        ============%0A    @Override%0A    public OptionalThing%3CObject%3E prepareDynamicData(SMailDynamicDataResource resourc
 e) %7B
@@ -1867,32 +1867,36 @@
 xists ? generate
+Data
 CacheKey(path, f
@@ -1892,39 +1892,15 @@
 Key(
-path, filesystem, receiverLocal
+resourc
 e) :
@@ -1942,30 +1942,30 @@
       final 
-String
+Object
  cached = Th
@@ -2059,16 +2059,41 @@
  return 
+OptionalThing.ofNullable(
 !cached.
@@ -2124,116 +2124,228 @@
 null
-;%0A            %7D%0A        %7D%0A        final String assisted = doAssist(postcard, path, filesystem, receiverLocal
+, () -%3E %7B%0A                    throw new IllegalStateException(%22Not found the dynamic data: %22 + resource);%0A                %7D);%0A            %7D%0A        %7D%0A        final OptionalThing%3CObject%3E assisted = loadDynamicData(resourc
 e);%0A
@@ -2382,20 +2382,16 @@
     
-if (
 assisted
  != 
@@ -2386,25 +2386,41 @@
 assisted
- != null)
+.ifPresent(dynamicData -%3E
  %7B%0A     
@@ -2473,79 +2473,19 @@
 ey, 
-assisted);%0A                return ThreadCacheContext.getObject(cacheKey
+dynamicData
 );%0A 
@@ -2488,37 +2488,46 @@
 );%0A            %7D
- else
+).orElse(() -%3E
  %7B%0A             
@@ -2615,38 +2615,40 @@
     
-    return null;%0A            %7D
+%7D);%0A            return assisted;
 %0A   
@@ -2699,32 +2699,215 @@
        %7D%0A    %7D%0A%0A
+    // -----------------------------------------------------%0A    //                                             Cache Key%0A    //                                             ---------%0A
     protected St
@@ -2919,16 +2919,20 @@
 generate
+Data
 CacheKey
@@ -2937,293 +2937,628 @@
 ey(S
-tring path, boolean filesystem, OptionalThing%3CLocale%3E receiverLocale) %7B%0A        return %22fw:mailText:%22 + path + %22:%22 + filesystem + %22:%22 + receiverLocale;%0A    %7D%0A%0A    protected abstract String doAssist(Postcard postcard, String path, boolean filesystem, OptionalThing%3CLocale%3E receiverLocal
+MailDynamicDataResource resource) %7B%0A        final String templatePath = resource.getTemplatePath();%0A        final boolean filesystem = resource.isFilesystem();%0A        final OptionalThing%3CLocale%3E receiverLocale = resource.getReceiverLocale();%0A        return %22fw:mailDynamicData:%22 + templatePath + %22:%22 + filesystem + %22:%22 + receiverLocale;%0A    %7D%0A%0A    // -----------------------------------------------------%0A    //                                                 Load%0A    //                                                ------%0A    protected abstract OptionalThing%3CObject%3E loadDynamicData(SMailDynamicDataResource resourc
 e);%0A

fix for mailflute improvement