001/*
002 *  Copyright 2016 Anyware Services
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 */
016package org.ametys.plugins.repository.script;
017
018import java.util.ArrayList;
019import java.util.HashMap;
020import java.util.List;
021import java.util.Map;
022
023import javax.jcr.Credentials;
024import javax.jcr.LoginException;
025import javax.jcr.NoSuchWorkspaceException;
026import javax.jcr.Node;
027import javax.jcr.NodeIterator;
028import javax.jcr.Repository;
029import javax.jcr.RepositoryException;
030import javax.jcr.Session;
031import javax.jcr.Value;
032import javax.script.ScriptException;
033
034import org.apache.avalon.framework.service.ServiceException;
035import org.apache.avalon.framework.service.ServiceManager;
036
037import org.ametys.plugins.core.ui.script.StaticConfigurableScriptBinding;
038import org.ametys.plugins.repository.AmetysObject;
039import org.ametys.plugins.repository.AmetysObjectIterable;
040import org.ametys.plugins.repository.AmetysObjectIterator;
041import org.ametys.plugins.repository.AmetysObjectResolver;
042import org.ametys.plugins.repositoryapp.RepositoryProvider;
043import org.ametys.runtime.i18n.I18nizableText;
044
045import com.google.common.collect.ImmutableMap;
046
047/**
048 * Script binding that provides repository variables
049 */
050public class RepositoryScriptBinding extends StaticConfigurableScriptBinding
051{
052    private RepositoryProvider _repositoryProvider;
053    private AmetysObjectResolver _ametysResolver;
054
055    @Override
056    public void service(ServiceManager serviceManager) throws ServiceException
057    {
058        super.service(serviceManager);
059        _repositoryProvider = (RepositoryProvider) serviceManager.lookup(RepositoryProvider.ROLE);
060        _ametysResolver = (AmetysObjectResolver) serviceManager.lookup(AmetysObjectResolver.ROLE);
061    }
062    
063    @Override
064    public Map<String, Object> getVariables()
065    {
066        Map<String, Object> variables = new HashMap<>();
067        Repository repository = _repositoryProvider.getRepository();
068        Credentials credentials = _repositoryProvider.getCredentials();
069        Session session;
070        
071        try
072        {
073            session = repository.login(credentials, "default");
074        }
075        catch (Exception e)
076        {
077            getLogger().warn("Unable to provides the JavaScript console with repository variables.", e);
078            return null;
079        }
080
081        variables.put("repository", new RepositoryWrapper(repository));
082        variables.put("session", session);
083        variables.put("ametysResolver", _ametysResolver);
084        return variables;
085    }
086
087    @Override
088    public Map<String, I18nizableText> getVariablesDescriptions()
089    {
090        return ImmutableMap.of("repository", new I18nizableText("plugin.repository", "PLUGINS_REPOSITORY_SCRIPT_VAR_REPOSITORY"),
091                               "session", new I18nizableText("plugin.repository", "PLUGINS_REPOSITORY_SCRIPT_VAR_SESSION"),
092                               "ametysResolver", new I18nizableText("plugin.repository", "PLUGINS_REPOSITORY_SCRIPT_VAR_AMETYSRESOLVER"),
093                               "ConsoleHelper", new I18nizableText("plugin.repository", "PLUGINS_REPOSITORY_SCRIPT_VAR_CONSOLEHELPER"));
094    }
095    
096    @Override
097    public void cleanVariables(Map<String, Object> variables)
098    {
099        if (variables.containsKey("session"))
100        {
101            Object session = variables.get("session");
102            if (session != null && session instanceof Session)
103            {
104                ((Session) session).logout();
105                variables.remove("session");
106            }
107        }
108    }
109    
110    @Override
111    public Object processScriptResult(Object result) throws ScriptException
112    {
113        try
114        {
115            if (result instanceof Node) 
116            {
117                // JCR Node
118                Node node = (Node) result;
119                
120                Map<String, String> props = new HashMap<>();
121                props.put("type", "node");
122                props.put("path", node.getPath());
123                props.put("workspace", node.getSession().getWorkspace().getName());
124                
125                return props;
126            } 
127            else if (result instanceof NodeIterator) 
128            {
129                // JCR NodeIterator
130                List<Object> nodePaths = new ArrayList<>();
131                
132                NodeIterator nodeIt = (NodeIterator) result;
133                while (nodeIt.hasNext())
134                {
135                    nodePaths.add(processScriptResult(nodeIt.nextNode()));
136                }
137                return nodePaths;
138            }
139            else if (result instanceof AmetysObject)
140            {
141                // Ametys Object
142                AmetysObject object = (AmetysObject) result;
143                
144                Map<String, String> props = new HashMap<>();
145                props.put("type", "ametys-object");
146                props.put("path", object.getPath());
147                props.put("id", object.getId());
148                return props;
149            }
150            else if (result instanceof AmetysObjectIterable<?>)
151            {
152                AmetysObjectIterator<?> iterator = ((AmetysObjectIterable<?>) result).iterator();
153                List<Object> objects = new ArrayList<>();
154                
155                while (iterator.hasNext())
156                {
157                    objects.add(processScriptResult(iterator.next()));
158                }
159                return objects;
160            }
161        }
162        catch (RepositoryException e)
163        {
164            throw new ScriptException(e);
165        }
166        
167        return null;
168    }
169
170    private class RepositoryWrapper implements Repository
171    {
172        private Repository _repo;
173        
174        RepositoryWrapper(Repository repo)
175        {
176            _repo = repo;
177        }
178
179        @Override
180        public String getDescriptor(String key)
181        {
182            return _repo.getDescriptor(key);
183        }
184
185        @Override
186        public String[] getDescriptorKeys()
187        {
188            return _repo.getDescriptorKeys();
189        }
190        
191        @Override
192        public Value getDescriptorValue(String key)
193        {
194            return _repo.getDescriptorValue(key);
195        }
196
197        @Override
198        public Value[] getDescriptorValues(String key)
199        {
200            return _repo.getDescriptorValues(key);
201        }
202
203        @Override
204        public boolean isSingleValueDescriptor(String key)
205        {
206            return _repo.isSingleValueDescriptor(key);
207        }
208        
209        @Override
210        public boolean isStandardDescriptor(String key)
211        {
212            return _repo.isStandardDescriptor(key);
213        }
214
215        @Override
216        public Session login() throws LoginException, RepositoryException
217        {
218            return _repo.login();
219        }
220
221        @Override
222        public Session login(Credentials credentials) throws LoginException, RepositoryException
223        {
224            return _repo.login(credentials);
225        }
226
227        @Override
228        public Session login(String workspaceName) throws LoginException, NoSuchWorkspaceException, RepositoryException
229        {
230            return _repo.login(workspaceName);
231        }
232
233        @Override
234        public Session login(Credentials credentials, String workspaceName) throws LoginException, NoSuchWorkspaceException, RepositoryException
235        {
236            return _repo.login(credentials, workspaceName);
237        }
238    }
239}