/*
 * Copyright 2014-2015 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.util;

import java.lang.reflect.Method;

import org.dbflute.helper.beans.DfBeanDesc;
import org.dbflute.helper.beans.exception.DfBeanMethodNotFoundException;
import org.dbflute.helper.beans.factory.DfBeanDescFactory;
import org.dbflute.jdbc.Classification;
import org.dbflute.util.DfReflectionUtil;

/**
 * @author jflute
 */
public class LaDBFluteUtil {

    public static boolean isClassificationType(Class<?> tp) {
        return Classification.class.isAssignableFrom(tp);
    }

    public static Classification toVerifiedClassification(Class<?> cdefType, Object code) throws ClassificationUnknownCodeException {
        if (code == null || (code instanceof String && ((String) code).isEmpty())) {
            return null;
        }
        final Classification cls = invokeClassificationCodeOf(cdefType, code);
        if (cls == null) {
            final String msg = "Unknow the classification code for " + cdefType.getName() + ": code=" + code;
            throw new ClassificationUnknownCodeException(msg);
        }
        return cls;
    }

    public static class ClassificationUnknownCodeException extends Exception { // checked

        private static final long serialVersionUID = 1L;

        public ClassificationUnknownCodeException(String msg) {
            super(msg);
        }
    }

    public static Classification invokeClassificationCodeOf(Class<?> cdefType, Object code) {
        assertArgumentNotNull("cdefType", cdefType);
        assertArgumentNotNull("code", code);
        if (code == null || (code instanceof String && ((String) code).isEmpty())) {
            return null;
        }
        final DfBeanDesc beanDesc = DfBeanDescFactory.getBeanDesc(cdefType);
        final String methodName = "codeOf";
        final Method method;
        try {
            method = beanDesc.getMethod(methodName, new Class<?>[] { Object.class });
        } catch (DfBeanMethodNotFoundException e) {
            String msg = "Failed to get the method " + methodName + "() of the classification type: " + cdefType;
            throw new ClassificationCodeOfMethodNotFoundException(msg, e);
        }
        return (Classification) DfReflectionUtil.invokeStatic(method, new Object[] { code });
    }

    public static class ClassificationCodeOfMethodNotFoundException extends RuntimeException {

        private static final long serialVersionUID = 1L;

        public ClassificationCodeOfMethodNotFoundException(String msg, DfBeanMethodNotFoundException e) {
            super(msg, e);
        }
    }

    protected static void assertArgumentNotNull(String variableName, Object value) {
        if (variableName == null) {
            String msg = "The value should not be null: variableName=null value=" + value;
            throw new IllegalArgumentException(msg);
        }
        if (value == null) {
            String msg = "The value should not be null: variableName=" + variableName;
            throw new IllegalArgumentException(msg);
        }
    }
}

@@ -693,32 +693,120 @@
 ort org.dbflute.
+jdbc.Classification;%0Aimport org.dbflute.util.DfReflectionUtil;%0Aimport org.lastaflute.di.
 helper.beans.DfB
@@ -802,18 +802,16 @@
 r.beans.
-Df
 BeanDesc
@@ -819,32 +819,38 @@
 %0Aimport org.
-db
+lasta
 flute.
+di.
 helper.beans
@@ -860,18 +860,16 @@
 ception.
-Df
 BeanMeth
@@ -900,24 +900,30 @@
 ort org.
-db
+lasta
 flute.
+di.
 helper.b
@@ -935,18 +935,16 @@
 factory.
-Df
 BeanDesc
@@ -955,90 +955,8 @@
 ory;
-%0Aimport org.dbflute.jdbc.Classification;%0Aimport org.dbflute.util.DfReflectionUtil;
 %0A%0A/*
@@ -2286,18 +2286,16 @@
   final 
-Df
 BeanDesc
@@ -2306,18 +2306,16 @@
 nDesc = 
-Df
 BeanDesc
@@ -2535,18 +2535,16 @@
  catch (
-Df
 BeanMeth
@@ -3093,18 +3093,16 @@
 ng msg, 
-Df
 BeanMeth

change to LastaDi's BeanDesc