001/*
002 * (C) Copyright 2006-2008 Nuxeo SAS (http://nuxeo.com/) and contributors.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the GNU Lesser General Public License
006 * (LGPL) version 2.1 which accompanies this distribution, and is available at
007 * http://www.gnu.org/licenses/lgpl.html
008 *
009 * This library is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012 * Lesser General Public License for more details.
013 *
014 * Contributors:
015 *     bstefanescu
016 *
017 * $Id$
018 */
019
020package org.nuxeo.ecm.webengine.rendering;
021
022import java.util.HashMap;
023import java.util.List;
024import java.util.Map;
025
026import org.nuxeo.ecm.webengine.WebEngine;
027import org.nuxeo.ecm.webengine.WebException;
028import org.nuxeo.ecm.webengine.model.WebContext;
029
030import freemarker.template.AdapterTemplateModel;
031import freemarker.template.SimpleScalar;
032import freemarker.template.TemplateCollectionModel;
033import freemarker.template.TemplateHashModelEx;
034import freemarker.template.TemplateMethodModelEx;
035import freemarker.template.TemplateModel;
036import freemarker.template.TemplateModelException;
037import freemarker.template.TemplateModelIterator;
038
039/**
040 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a>
041 */
042public class ScriptMethod implements TemplateMethodModelEx {
043
044    public Object exec(List arguments) throws TemplateModelException {
045        int size = arguments.size();
046        if (size < 1) {
047            throw new TemplateModelException("Invalid number of arguments for script(...) method");
048        }
049
050        SimpleScalar val = (SimpleScalar) arguments.get(0);
051        if (val == null) {
052            throw new TemplateModelException("src attribute is required");
053        }
054        String src = val.getAsString();
055
056        Map<String, Object> args = new HashMap<String, Object>();
057        if (arguments.size() > 1) {
058            Object o = arguments.get(1);
059            if (o instanceof SimpleScalar) {
060                String arg = ((SimpleScalar) o).getAsString();
061                args.put("_args", new String[] { arg });
062            } else if (!(o instanceof TemplateHashModelEx)) {
063                throw new TemplateModelException("second argument should be a map");
064            } else {
065                TemplateHashModelEx t = (TemplateHashModelEx) o;
066                TemplateCollectionModel keys = t.keys();
067                TemplateModelIterator it = keys.iterator();
068
069                while (it.hasNext()) {
070                    TemplateModel k = it.next();
071                    String kk = k.toString();
072                    TemplateModel v = t.get(kk);
073                    Object vv = null;
074                    if (v instanceof AdapterTemplateModel) {
075                        vv = ((AdapterTemplateModel) v).getAdaptedObject(null);
076                    } else {
077                        vv = v.toString();
078                    }
079                    args.put(kk, vv);
080                }
081            }
082        }
083
084        WebContext ctx = WebEngine.getActiveContext();
085        if (ctx != null) {
086            try {
087                return ctx.runScript(src, args);
088            } catch (WebException e) {
089                throw new TemplateModelException("Failed to run script: " + src, e);
090            }
091        } else {
092            throw new IllegalStateException("Not In a Web Context");
093        }
094    }
095
096}