001package org.apache.archiva.redback.role.util;
002
003/*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements.  See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership.  The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License.  You may obtain a copy of the License at
011 *
012 * http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied.  See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021
022import org.apache.archiva.components.graph.api.Category;
023import org.apache.archiva.components.graph.api.RelationType;
024import org.apache.archiva.components.graph.base.SimpleGraph;
025import org.apache.archiva.components.graph.base.SimpleNode;
026import org.apache.archiva.components.graph.util.Traversal;
027import org.apache.archiva.redback.role.model.ModelApplication;
028import org.apache.archiva.redback.role.model.ModelOperation;
029import org.apache.archiva.redback.role.model.ModelResource;
030import org.apache.archiva.redback.role.model.ModelRole;
031import org.apache.archiva.redback.role.model.ModelTemplate;
032import org.apache.archiva.redback.role.model.RedbackRoleModel;
033import org.slf4j.Logger;
034import org.slf4j.LoggerFactory;
035
036import java.util.ArrayList;
037import java.util.Collections;
038import java.util.LinkedList;
039import java.util.List;
040import java.util.stream.Collectors;
041
042/**
043 * RoleModelUtils:
044 *
045 * @author: Jesse McConnell
046 *
047 */
048public class RoleModelUtils
049{
050    public enum RoleType implements Category {
051        ROLE,TEMPLATE
052    }
053
054    public enum RoleRelation implements RelationType {
055        ROLE_TO_ROLE,ROLE_TO_TEMPLATE,TEMPLATE_TO_ROLE,TEMPLATE_TO_TEMPLATE;
056    }
057
058    public static final String ROOT = ":archiva:node:root";
059
060    private static final Logger log = LoggerFactory.getLogger(RoleModelUtils.class);
061
062    public static List<ModelRole> getRoles( RedbackRoleModel model )
063    {
064        List<ModelRole> roleList = new ArrayList<ModelRole>( );
065
066        for ( ModelApplication application : model.getApplications() )
067        {
068            roleList.addAll( application.getRoles() );
069        }
070
071        return roleList;
072    }
073
074    public static List<ModelTemplate> getTemplates( RedbackRoleModel model )
075    {
076        List<ModelTemplate> templateList = new ArrayList<ModelTemplate>();
077
078        for ( ModelApplication application : model.getApplications() )
079        {
080            templateList.addAll( application.getTemplates() );
081        }
082
083        return templateList;
084    }
085
086    @SuppressWarnings( "unchecked" )
087    public static List<String> getOperationIdList( RedbackRoleModel model )
088    {
089        List<String> operationsIdList = new ArrayList<String>();
090
091        for ( ModelApplication application : model.getApplications() )
092        {
093            for ( ModelOperation operation : application.getOperations() )
094            {
095                operationsIdList.add( operation.getId() );
096            }
097        }
098
099        return operationsIdList;
100    }
101
102    @SuppressWarnings( "unchecked" )
103    public static List<String> getResourceIdList( RedbackRoleModel model )
104    {
105        List<String> resourceIdList = new ArrayList<String>();
106
107        for ( ModelApplication application : model.getApplications() )
108        {
109            for ( ModelResource resource : application.getResources() )
110            {
111                resourceIdList.add( resource.getId() );
112            }
113        }
114
115        return resourceIdList;
116    }
117
118    public static List<String> getRoleIdList( RedbackRoleModel model )
119    {
120        List<String> roleIdList = new ArrayList<String>();
121
122        for ( ModelApplication application : model.getApplications() )
123        {
124            for ( ModelRole role : application.getRoles() )
125            {
126                roleIdList.add( role.getId() );
127            }
128        }
129
130        return roleIdList;
131    }
132
133
134    public static List<String> getTemplateIdList( RedbackRoleModel model )
135    {
136        List<String> templateIdList = new ArrayList<String>();
137
138        for ( ModelApplication application : model.getApplications() )
139        {
140            for ( ModelTemplate template : application.getTemplates() )
141            {
142                templateIdList.add( template.getId() );
143            }
144        }
145
146        return templateIdList;
147
148    }
149
150    /**
151     * WARNING: can return null
152     *
153     * @param model
154     * @param roleId
155     * @return
156     */
157    @SuppressWarnings( "unchecked" )
158    public static ModelRole getModelRole( RedbackRoleModel model, String roleId )
159    {
160        ModelRole mrole = null;
161
162        for ( ModelApplication application : model.getApplications() )
163        {
164            for ( ModelRole role : application.getRoles() )
165            {
166                if ( roleId.equals( role.getId() ) )
167                {
168                    mrole = role;
169                }
170            }
171        }
172
173        return mrole;
174    }
175
176    /**
177     * WARNING: can return null
178     *
179     * @param model
180     * @param templateId
181     * @return
182     */
183    @SuppressWarnings( "unchecked" )
184    public static ModelTemplate getModelTemplate( RedbackRoleModel model, String templateId )
185    {
186        ModelTemplate mtemplate = null;
187
188        for ( ModelApplication application : model.getApplications() )
189        {
190            for ( ModelTemplate template : application.getTemplates() )
191            {
192                if ( templateId.equals( template.getId() ) )
193                {
194                    mtemplate = template;
195                }
196            }
197        }
198
199        return mtemplate;
200    }
201
202    /**
203     * WARNING: can return null
204     *
205     * @param model
206     * @param operationId
207     * @return
208     */
209    @SuppressWarnings( "unchecked" )
210    public static ModelOperation getModelOperation( RedbackRoleModel model, String operationId )
211    {
212        ModelOperation moperation = null;
213
214        for ( ModelApplication application : model.getApplications() )
215        {
216            for ( ModelOperation operation : application.getOperations() )
217            {
218                if ( operationId.equals( operation.getId() ) )
219                {
220                    moperation = operation;
221                }
222            }
223        }
224
225        return moperation;
226    }
227
228    @SuppressWarnings( "unchecked" )
229    public static ModelResource getModelResource( RedbackRoleModel model, String resourceId )
230    {
231        ModelResource mresource = null;
232
233        for ( ModelApplication application : model.getApplications() )
234        {
235            for ( ModelResource resource : application.getResources() )
236            {
237                if ( resourceId.equals( resource.getId() ) )
238                {
239                    mresource = resource;
240                }
241            }
242        }
243
244        return mresource;
245    }
246
247    @SuppressWarnings( "unchecked" )
248    public static SimpleGraph generateRoleGraph(RedbackRoleModel model )
249
250    {
251        SimpleGraph roleGraph = new SimpleGraph();
252        SimpleNode rootNode = roleGraph.addNode(ROOT, ROOT);
253
254        log.debug("Created graph with root {}", rootNode);
255
256        for ( ModelApplication application : model.getApplications() )
257        {
258            log.debug("Application {}", application.getId());
259            for ( ModelRole role : application.getRoles() )
260            {
261                final String roleId = role.getId();
262                SimpleNode roleNode = roleGraph.addNode(roleId, roleId);
263                roleNode.addCategory(RoleType.ROLE);
264                if (role.getParentRoles()==null || role.getParentRoles().size()==0) {
265                    // We add it to the root node only, if it has no parent roles
266                    roleGraph.addEdge("root:" + roleId, "root -> " + roleId, rootNode, roleNode);
267                }
268
269                if ( role.getChildRoles() != null )
270                {
271                    for ( String childRole : role.getChildRoles() )
272                    {
273                        SimpleNode childNode = roleGraph.addNode(childRole, childRole);
274                        childNode.addCategory(RoleType.ROLE);
275                        roleGraph.addEdge( RoleRelation.ROLE_TO_ROLE, roleId+":"+childRole,
276                                roleId+" -> "+childRole, roleNode, childNode );
277
278                    }
279                }
280
281                if ( role.getParentRoles() != null )
282                {
283                    for ( String parentRole : role.getParentRoles() )
284                    {
285                        SimpleNode parentNode = roleGraph.addNode( parentRole, parentRole );
286                        parentNode.addCategory(RoleType.ROLE);
287                        roleGraph.addEdge( RoleRelation.ROLE_TO_ROLE, parentRole+":"+roleId,
288                                parentRole + " -> "+ roleId, parentNode, roleNode);
289                    }
290                }
291            }
292        }
293
294        return roleGraph;
295    }
296
297    @SuppressWarnings( "unchecked" )
298    public static SimpleGraph generateTemplateGraph( RedbackRoleModel model )
299
300    {
301        SimpleGraph templateGraph = generateRoleGraph( model );
302        SimpleNode rootNode = templateGraph.getNode(ROOT);
303
304        for ( ModelApplication application : model.getApplications() )
305        {
306            for ( ModelTemplate template : application.getTemplates() )
307            {
308                final String templId = template.getId();
309                SimpleNode templateNode = templateGraph.addNode(templId, templId);
310                templateNode.addCategory(RoleType.TEMPLATE);
311                if ((template.getParentRoles() == null || template.getParentRoles().size()==0)
312                && ( template.getParentTemplates() == null || template.getParentTemplates().size()==0) ) {
313                    templateGraph.addEdge("root:" + templId, "root -> " + templId, rootNode, templateNode);
314                }
315
316                if ( template.getChildRoles() != null )
317                {
318                    for ( String childRole : template.getChildRoles() )
319                    {
320                        SimpleNode childNode = templateGraph.addNode(childRole, childRole);
321                        childNode.addCategory(RoleType.ROLE);
322                        templateGraph.addEdge( RoleRelation.TEMPLATE_TO_ROLE, templId+":"+childNode, templId+" -> "+childNode, templateNode, childNode );
323                    }
324                }
325
326                if ( template.getParentRoles() != null )
327                {
328                    for ( String parentRole : template.getParentRoles() )
329                    {
330                        SimpleNode parentNode = templateGraph.addNode(parentRole, parentRole);
331                        parentNode.addCategory(RoleType.ROLE);
332                        templateGraph.addEdge( RoleRelation.ROLE_TO_TEMPLATE, parentRole+":"+templId,
333                                parentRole+" -> "+templId, parentNode, templateNode);
334                    }
335                }
336
337                if ( template.getChildTemplates() != null )
338                {
339                    for ( String childTemplate : template.getChildTemplates() )
340                    {
341                        SimpleNode childTemplNode = templateGraph.addNode(childTemplate, childTemplate);
342                        childTemplNode.addCategory(RoleType.TEMPLATE);
343                        templateGraph.addEdge( RoleRelation.TEMPLATE_TO_TEMPLATE, templId+":"+childTemplate,
344                                templId+" -> "+childTemplate, templateNode, childTemplNode);
345                    }
346                }
347
348                if ( template.getParentTemplates() != null )
349                {
350                    for ( String parentTemplate : template.getParentTemplates() )
351                    {
352                        SimpleNode parentTemplNode = templateGraph.addNode( parentTemplate, parentTemplate );
353                        parentTemplNode.addCategory(RoleType.TEMPLATE);
354                        templateGraph.addEdge( RoleRelation.TEMPLATE_TO_TEMPLATE,
355                                parentTemplate+":"+templId, parentTemplate+" -> "+templId,
356                                parentTemplNode, templateNode);
357                    }
358                }
359            }
360        }
361
362        return templateGraph;
363    }
364
365    @SuppressWarnings( "unchecked" )
366    public static List<String> reverseTopologicalSortedRoleList( RedbackRoleModel model )
367    {
368        SimpleGraph graph = generateRoleGraph(model);
369        List<String> sortedGraph = Traversal.topologialSort(graph.getNode(ROOT)).stream().map(n -> n.getId())
370                .filter(id -> !ROOT.equals(id)).collect(Collectors.toList());
371        Collections.reverse(sortedGraph);
372        return sortedGraph;
373    }
374
375    public static String getRoleId( String templateId, String resource) {
376        return templateId + "." + resource;
377    }
378
379}