001/*
002 * (C) Copyright 2015-2017 Nuxeo (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     Thierry Delprat <tdelprat@nuxeo.com>
018 *     Stephane Lacoin <slacoin@nuxeo.com>
019 *     Vladimir Pasquier <vpasquier@nuxeo.com>
020 */
021package org.nuxeo.automation.scripting.internals;
022
023import java.util.ArrayList;
024import java.util.HashSet;
025import java.util.List;
026import java.util.Set;
027
028import org.apache.commons.logging.Log;
029import org.apache.commons.logging.LogFactory;
030import org.nuxeo.automation.scripting.api.AutomationScriptingService;
031import org.nuxeo.ecm.automation.AutomationService;
032import org.nuxeo.runtime.api.Framework;
033import org.nuxeo.runtime.model.ComponentContext;
034import org.nuxeo.runtime.model.ComponentInstance;
035import org.nuxeo.runtime.model.DefaultComponent;
036import org.nuxeo.runtime.services.config.ConfigurationService;
037
038/**
039 * @since 7.2
040 */
041public class AutomationScriptingComponent extends DefaultComponent {
042
043    private static final Log log = LogFactory.getLog(AutomationScriptingComponent.class);
044
045    protected static final String XP_OPERATION = "operation";
046
047    protected static final String XP_CLASSFILTER = "classFilter";
048
049    protected final AutomationScriptingServiceImpl service = new AutomationScriptingServiceImpl();
050
051    protected final AutomationScriptingRegistry registry = new AutomationScriptingRegistry();
052
053    protected final List<ClassFilterDescriptor> classFilterDescriptors = new ArrayList<>();
054
055    @Override
056    public void activate(ComponentContext context) {
057        registry.automation = Framework.getService(AutomationService.class);
058        registry.scripting = service;
059    }
060
061    @Override
062    public void start(ComponentContext context) {
063        boolean inlinedContext = Framework.getService(ConfigurationService.class)
064                                          .isBooleanPropertyTrue("nuxeo.automation.scripting.inline-context-in-params");
065
066        service.paramsInjector = AutomationScriptingParamsInjector.newInstance(inlinedContext);
067    }
068
069    @Override
070    public void registerContribution(Object contribution, String extensionPoint, ComponentInstance contributor) {
071        if (XP_OPERATION.equals(extensionPoint)) {
072            registry.addContribution((ScriptingOperationDescriptor) contribution);
073        } else if (XP_CLASSFILTER.equals(extensionPoint)) {
074            registerClassFilter((ClassFilterDescriptor) contribution);
075        } else {
076            log.error("Unknown extension point " + extensionPoint);
077        }
078    }
079
080    @Override
081    public void unregisterContribution(Object contribution, String extensionPoint, ComponentInstance contributor) {
082        if (XP_OPERATION.equals(extensionPoint)) {
083            registry.removeContribution((ScriptingOperationDescriptor) contribution);
084        } else if (XP_CLASSFILTER.equals(extensionPoint)) {
085            unregisterClassFilter((ClassFilterDescriptor) contribution);
086        } else {
087            log.error("Unknown extension point " + extensionPoint);
088        }
089    }
090
091    protected void registerClassFilter(ClassFilterDescriptor desc) {
092        classFilterDescriptors.add(desc);
093        recomputeClassFilters();
094    }
095
096    protected void unregisterClassFilter(ClassFilterDescriptor desc) {
097        classFilterDescriptors.remove(desc);
098        recomputeClassFilters();
099    }
100
101    protected void recomputeClassFilters() {
102        Set<String> allowedClassNames = new HashSet<>();
103        for (ClassFilterDescriptor desc : classFilterDescriptors) {
104            if (desc.deny.contains("*")) {
105                allowedClassNames.clear();
106                allowedClassNames.addAll(desc.allow);
107            } else {
108                allowedClassNames.addAll(desc.allow);
109                allowedClassNames.removeAll(desc.deny);
110            }
111        }
112        // we don't care about update atomicity, as nothing executes concurrently with XML config
113        service.allowedClassNames.clear();
114        service.allowedClassNames.addAll(allowedClassNames);
115    }
116
117    @Override
118    public <T> T getAdapter(Class<T> adapter) {
119        if (adapter.isAssignableFrom(AutomationScriptingService.class)) {
120            return adapter.cast(service);
121        }
122        return super.getAdapter(adapter);
123    }
124
125}