Object eval()

in freemarker-core/src/main/java/freemarker/core/_ObjectBuilderSettingEvaluator.java [863:959]


        Object eval() throws _ObjectBuilderSettingEvaluationException {
            if (mustBeStaticField) {
                if (!canBeStaticField) {
                    throw new BugException();
                }
                return getStaticFieldValue(className);
            }
            
            Class cl;
            
            if (!modernMode) {
                try {
                    try {
                        return ClassUtil.forName(className).newInstance();
                    } catch (InstantiationException e) {
                        throw new LegacyExceptionWrapperSettingEvaluationExpression(e);
                    } catch (IllegalAccessException e) {
                        throw new LegacyExceptionWrapperSettingEvaluationExpression(e);
                    } catch (ClassNotFoundException e) {
                        throw new LegacyExceptionWrapperSettingEvaluationExpression(e);
                    }
                } catch (LegacyExceptionWrapperSettingEvaluationExpression e) {
                    if (!canBeStaticField || className.indexOf('.') == -1) {
                        throw e;
                    }
                    // Silently try to interpret className as static filed, throw the original exception if that fails. 
                    try {
                        return getStaticFieldValue(className);
                    } catch (_ObjectBuilderSettingEvaluationException e2) {
                        throw e;
                    }
                }
            }

            boolean clIsBuilderClass;
            try {
                cl = ClassUtil.forName(className + BUILDER_CLASS_POSTFIX);
                clIsBuilderClass = true;
            } catch (ClassNotFoundException e) {
                clIsBuilderClass = false;
                try {
                    cl = ClassUtil.forName(className);
                } catch (Exception e2) {
                    boolean failedToGetAsStaticField;
                    if (canBeStaticField) {
                        // Try to interpret className as static filed: 
                        try {
                            return getStaticFieldValue(className);
                        } catch (_ObjectBuilderSettingEvaluationException e3) {
                            // Suppress it
                            failedToGetAsStaticField = true;
                        }
                    } else {
                        failedToGetAsStaticField = false;
                    }
                    throw new _ObjectBuilderSettingEvaluationException(
                            "Failed to get class " + StringUtil.jQuote(className)
                            + (failedToGetAsStaticField ? " (also failed to resolve name as static field)" : "")
                            + ".",
                            e2);
                }
            }
            
            if (!clIsBuilderClass && hasNoParameters()) {
                try {
                    Field f = cl.getField(INSTANCE_FIELD_NAME);
                    if ((f.getModifiers() & (Modifier.PUBLIC | Modifier.STATIC))
                            == (Modifier.PUBLIC | Modifier.STATIC)) {
                        return f.get(null);
                    }
                } catch (NoSuchFieldException e) {
                    // Expected
                } catch (Exception e) {
                    throw new _ObjectBuilderSettingEvaluationException(
                            "Error when trying to access " + StringUtil.jQuote(className) + "."
                            + INSTANCE_FIELD_NAME, e);
                }
            }
            
            // Create the object to return or its builder:
            Object constructorResult = callConstructor(cl);
            
            // Named parameters will set JavaBeans properties:
            setJavaBeanProperties(constructorResult, namedParamNames, namedParamValues);

            final Object result;
            if (clIsBuilderClass) {
                result = callBuild(constructorResult);
            } else {
                if (constructorResult instanceof WriteProtectable) {
                    ((WriteProtectable) constructorResult).writeProtect();
                }
                result = constructorResult;
            }
            
            return result;
        }