001/*
002 * (C) Copyright 2006-2015 Nuxeo SA (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-2.1.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 *     Nuxeo - initial API and implementation
016 *
017 */
018
019package org.nuxeo.usermapper.extension;
020
021import groovy.lang.Binding;
022import groovy.lang.GroovyClassLoader;
023import groovy.lang.Script;
024
025import java.io.IOException;
026import java.io.Serializable;
027import java.util.HashMap;
028import java.util.Map;
029
030import org.apache.commons.lang.StringUtils;
031import org.codehaus.groovy.runtime.InvokerHelper;
032import org.nuxeo.ecm.core.api.NuxeoPrincipal;
033
034/**
035 * Implement the {@link UserMapper} using Groovy Scripting for the mapping part
036 *
037 * @author tiry
038 * @since 7.4
039 */
040public class GroovyUserMapper extends AbstractUserMapper {
041
042    protected final String mapperSource;
043
044    protected final String wrapperSource;
045
046    protected GroovyClassLoader loader;
047
048    protected Class<?> mapperClass;
049
050    protected Class<?> wrapperClass;
051
052    public GroovyUserMapper(String mapperScript, String wrapperScript) {
053        super();
054        mapperSource = mapperScript;
055        wrapperSource = wrapperScript;
056    }
057
058    @Override
059    public void init(Map<String, String> params) {
060        loader = new GroovyClassLoader(this.getClass().getClassLoader());
061        mapperClass = loader.parseClass(mapperSource);
062        if (!StringUtils.isEmpty(wrapperSource)) {
063            wrapperClass = loader.parseClass(wrapperSource);
064        }
065    }
066
067    @Override
068    protected void resolveAttributes(Object userObject, Map<String, Serializable> searchAttributes,
069            Map<String, Serializable> userAttributes, Map<String, Serializable> profileAttributes) {
070        Map<String, Object> context = new HashMap<>();
071        context.put("searchAttributes", searchAttributes);
072        context.put("profileAttributes", profileAttributes);
073        context.put("userAttributes", userAttributes);
074        context.put("userObject", userObject);
075        Binding binding = new Binding(context);
076        Script script = InvokerHelper.createScript(mapperClass, binding);
077        script.run();
078    }
079
080    @Override
081    public Object wrapNuxeoPrincipal(NuxeoPrincipal principal, Object userObject, Map<String, Serializable> params) {
082        Map<String, Object> context = new HashMap<>();
083        context.put("nuxeoPrincipal", principal);
084        context.put("userObject", userObject);
085        context.put("params", params);
086        Binding binding = new Binding(context);
087        Script script = InvokerHelper.createScript(wrapperClass, binding);
088        script.run();
089        return context.get("userObject");
090    }
091
092    @Override
093    public void release() {
094        loader.clearCache();
095        try {
096            loader.close();
097        } catch (IOException e) {
098            log.error("Error during Groovy cleanup", e);
099        }
100    }
101
102}