001/*
002 * Copyright (c) 2006-2011 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the Eclipse Public License v1.0
006 * which accompanies this distribution, and is available at
007 * http://www.eclipse.org/legal/epl-v10.html
008 *
009 * Contributors:
010 *     bstefanescu
011 *
012 * $Id$
013 */
014
015package org.nuxeo.ecm.platform.rendering.fm.extensions;
016
017import java.lang.reflect.Constructor;
018import java.util.List;
019
020import freemarker.template.TemplateMethodModelEx;
021import freemarker.template.TemplateModelException;
022
023/**
024 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a>
025 */
026public class NewMethod implements TemplateMethodModelEx {
027
028    public Object exec(List arguments) throws TemplateModelException {
029        int size = arguments.size();
030        if (size < 1) {
031            throw new TemplateModelException("Invalid number of arguments for new(class, ...) method");
032        }
033
034        Class<?> klass;
035        try {
036            String className = (String) arguments.get(0);
037            klass = Class.forName(className);
038            if (size == 1) {
039                return klass.newInstance();
040            }
041        } catch (ReflectiveOperationException e) {
042            throw new TemplateModelException("Failed to isntantiate the object", e);
043        }
044        arguments.remove(0);
045        Object[] ar = arguments.toArray();
046        size--;
047        Constructor<?>[] ctors = klass.getConstructors();
048        for (Constructor<?> ctor : ctors) {
049            Class<?>[] params = ctor.getParameterTypes(); // this is cloning params
050            if (params.length == size) { // try this one
051                try {
052                    return ctor.newInstance(ar);
053                } catch (ReflectiveOperationException e) {
054                    // continue
055                }
056            }
057        }
058        throw new TemplateModelException("No suitable constructor found");
059    }
060
061}