]> source.dussan.org Git - archiva.git/commitdiff
[MRM-694]
authorMaria Odea B. Ching <oching@apache.org>
Mon, 12 May 2008 07:57:06 +0000 (07:57 +0000)
committerMaria Odea B. Ching <oching@apache.org>
Mon, 12 May 2008 07:57:06 +0000 (07:57 +0000)
patch submitted by Maria Catherine Tan
-UI for repository groups
-test cases for action classes

git-svn-id: https://svn.apache.org/repos/asf/archiva/trunk@655432 13f79535-47bb-0310-9956-ffa450edef68

12 files changed:
archiva-modules/archiva-base/archiva-configuration/src/main/mdo/configuration.mdo
archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/action/admin/repositories/DeleteRepositoryGroupAction.java [new file with mode: 0644]
archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/action/admin/repositories/RepositoryGroupsAction.java [new file with mode: 0644]
archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/action/admin/repositories/SortRepositoriesAction.java [new file with mode: 0644]
archiva-modules/archiva-web/archiva-webapp/src/main/resources/xwork.xml
archiva-modules/archiva-web/archiva-webapp/src/main/webapp/WEB-INF/jsp/admin/deleteRepositoryGroup.jsp [new file with mode: 0644]
archiva-modules/archiva-web/archiva-webapp/src/main/webapp/WEB-INF/jsp/admin/repositoryGroups.jsp [new file with mode: 0644]
archiva-modules/archiva-web/archiva-webapp/src/main/webapp/WEB-INF/jsp/decorators/default.jsp
archiva-modules/archiva-web/archiva-webapp/src/main/webapp/css/site.css
archiva-modules/archiva-web/archiva-webapp/src/test/java/org/apache/maven/archiva/web/action/admin/repositories/DeleteRepositoryGroupActionTest.java [new file with mode: 0644]
archiva-modules/archiva-web/archiva-webapp/src/test/java/org/apache/maven/archiva/web/action/admin/repositories/RepositoryGroupsActionTest.java [new file with mode: 0644]
archiva-modules/archiva-web/archiva-webapp/src/test/java/org/apache/maven/archiva/web/action/admin/repositories/SortRepositoriesActionTest.java [new file with mode: 0644]

index 57770b885bd680af4bf5220ad0c1f4c690e01191..1455d9f71b3ffa0557e979fae2343f9b1ebd4f1f 100644 (file)
     
     public java.util.Map<String, java.util.List<String>> getRepositoryToGroupMap()
     {
-        if ( repositoryToGroupMap == null )
+        if ( repositoryGroups != null )
         {
             java.util.Map<String, java.util.List<String>> map = new java.util.HashMap<String, java.util.List<String>>();
             
         }
         return repositoryToGroupMap;
     }
+    
+    public java.util.Map<String, RepositoryGroupConfiguration> getRepositoryGroupsAsMap()
+    {
+        java.util.Map<String, RepositoryGroupConfiguration> map = new java.util.HashMap<String, RepositoryGroupConfiguration>();
+        if ( repositoryGroups != null )
+        {
+            for ( RepositoryGroupConfiguration group : (java.util.List<RepositoryGroupConfiguration>) repositoryGroups )
+            {
+                map.put( group.getId(), group );
+            }
+        }
+        return map;
+    }
+    
+    public RepositoryGroupConfiguration findRepositoryGroupById( String id )
+    {
+        if ( repositoryGroups != null )
+        {
+            for ( RepositoryGroupConfiguration group : (java.util.List<RepositoryGroupConfiguration>) repositoryGroups )
+            {
+                if ( group.getId().equals( id ) )
+                {
+                    return group;
+                }
+            }
+        }
+        return null;
+    }
+
+    private java.util.Map<String, java.util.List<String>> groupToRepositoryMap;
+       
+    public java.util.Map<String, java.util.List<String>> getGroupToRepositoryMap()
+    {
+       if ( repositoryGroups != null && managedRepositories != null )
+        {
+            java.util.Map<String, java.util.List<String>> map = new java.util.HashMap<String, java.util.List<String>>();
+            
+            for ( ManagedRepositoryConfiguration repo : (java.util.List<ManagedRepositoryConfiguration>) managedRepositories )
+            {
+                for ( RepositoryGroupConfiguration group : (java.util.List<RepositoryGroupConfiguration>) repositoryGroups )
+                {
+                    if ( !group.getRepositories().contains( repo.getId() ) )
+                    {
+                        String groupId = group.getId();
+                        java.util.List<String> repos = map.get( groupId );
+                        if ( repos == null )
+                        {
+                            repos = new java.util.ArrayList<String>();
+                            map.put( groupId, repos );
+                        }
+                        repos.add( repo.getId() );
+                    }
+                }
+            }
+            groupToRepositoryMap = map;
+        }
+        return groupToRepositoryMap;
+    }
           ]]></code>
         </codeSegment>
         <codeSegment>
diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/action/admin/repositories/DeleteRepositoryGroupAction.java b/archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/action/admin/repositories/DeleteRepositoryGroupAction.java
new file mode 100644 (file)
index 0000000..653a293
--- /dev/null
@@ -0,0 +1,96 @@
+package org.apache.maven.archiva.web.action.admin.repositories;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import com.opensymphony.xwork.Preparable;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.maven.archiva.configuration.Configuration;
+import org.apache.maven.archiva.configuration.RepositoryGroupConfiguration;
+
+/**
+ * DeleteRepositoryGroupAction
+ * 
+ * @author
+ * @version
+ * @plexus.component role="com.opensymphony.xwork.Action" role-hint="deleteRepositoryGroupAction"
+ */
+public class DeleteRepositoryGroupAction 
+    extends AbstractRepositoriesAdminAction
+    implements Preparable
+{
+    private RepositoryGroupConfiguration repositoryGroup;
+
+    private String repoGroupId;
+       
+    public void prepare()
+    {
+        if ( StringUtils.isNotBlank( repoGroupId ) )
+        {
+            this.repositoryGroup = archivaConfiguration.getConfiguration().findRepositoryGroupById( repoGroupId );
+        }
+    }
+       
+    public String confirmDelete()
+    {
+        if ( StringUtils.isBlank( repoGroupId ) )
+        {
+            addActionError( "Unable to delete repository group: repository id was blank." );
+            return ERROR;
+        }
+
+        return INPUT;
+    }
+
+    public String delete()
+    {
+        Configuration config = archivaConfiguration.getConfiguration();
+
+        RepositoryGroupConfiguration group = config.findRepositoryGroupById( repoGroupId );
+        if ( group == null )
+        {
+            addActionError( "A repository group with that id does not exist." );
+            return ERROR;
+        }
+               
+        config.removeRepositoryGroup( group );
+        return saveConfiguration( config );
+    }
+       
+    public RepositoryGroupConfiguration getRepositoryGroup()
+    {
+        return repositoryGroup;
+    }
+
+    public void setRepositoryGroup( RepositoryGroupConfiguration repositoryGroup )
+    {
+        this.repositoryGroup = repositoryGroup;
+    }
+
+    public String getRepoGroupId()
+    {
+        return repoGroupId;
+    }
+
+    public void setRepoGroupId( String repoGroupId )
+    {
+        this.repoGroupId = repoGroupId;
+    }
+}
diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/action/admin/repositories/RepositoryGroupsAction.java b/archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/action/admin/repositories/RepositoryGroupsAction.java
new file mode 100644 (file)
index 0000000..d01cc9b
--- /dev/null
@@ -0,0 +1,231 @@
+package org.apache.maven.archiva.web.action.admin.repositories;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import javax.servlet.http.HttpServletRequest;
+
+import com.opensymphony.webwork.interceptor.ServletRequestAware;
+import com.opensymphony.xwork.Preparable;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.maven.archiva.configuration.ArchivaConfiguration;
+import org.apache.maven.archiva.configuration.Configuration;
+import org.apache.maven.archiva.configuration.ManagedRepositoryConfiguration;
+import org.apache.maven.archiva.configuration.RepositoryGroupConfiguration;
+import org.apache.maven.archiva.security.ArchivaRoleConstants;
+import org.apache.maven.archiva.web.util.ContextUtils;
+
+/**
+ * RepositoryGroupsAction
+ * 
+ * @author
+ * @version
+ * @plexus.component role="com.opensymphony.xwork.Action" role-hint="repositoryGroupsAction"
+ */
+public class RepositoryGroupsAction
+    extends AbstractRepositoriesAdminAction
+    implements ServletRequestAware, Preparable
+{
+    private RepositoryGroupConfiguration repositoryGroup;
+
+    private Map<String, RepositoryGroupConfiguration> repositoryGroups;
+
+    private Map<String, ManagedRepositoryConfiguration> managedRepositories;
+
+    private Map<String, List<String>> groupToRepositoryMap;
+
+    private String repoGroupId;
+    
+    private String repoId;
+
+    /**
+     * Used to construct the repository WebDAV URL in the repository action.
+     */
+    private String baseUrl;
+    
+    public void setServletRequest( HttpServletRequest request )
+    {
+        this.baseUrl = ContextUtils.getBaseURL( request, "repository" );
+    }
+
+    public void prepare()
+    {
+        Configuration config = archivaConfiguration.getConfiguration();
+        
+        repositoryGroup = new RepositoryGroupConfiguration();
+        repositoryGroups = config.getRepositoryGroupsAsMap();
+        managedRepositories = config.getManagedRepositoriesAsMap();
+        groupToRepositoryMap = config.getGroupToRepositoryMap();
+    }
+    
+    public String addRepositoryGroup()
+    {
+        Configuration configuration = archivaConfiguration.getConfiguration();
+
+        String repoGroupId = repositoryGroup.getId();
+        
+        if ( StringUtils.isBlank( repoGroupId ) )
+        {
+               addActionError( "You must enter a repository group id." );
+               return ERROR;
+        }
+        
+        if ( configuration.getRepositoryGroupsAsMap().containsKey( repoGroupId ) )
+        {
+            addActionError( "Unable to add new repository group with id [" + repoGroupId
+                    + "], that id already exists." );
+            return ERROR;
+        }
+        
+        configuration.addRepositoryGroup( repositoryGroup );
+        return saveConfiguration( configuration );
+    }
+    
+    public String addRepositoryToGroup()
+    {
+        Configuration config = archivaConfiguration.getConfiguration();
+        RepositoryGroupConfiguration group = config.findRepositoryGroupById( repoGroupId );
+       
+        validateRepository();
+       
+        if ( hasErrors() )
+        {
+            return ERROR;
+        }
+
+        if ( group.getRepositories().contains( repoId ) )
+        {
+            addActionError( "Repository with id [" + repoId + "] is already in the group" );
+            return ERROR;
+        }
+
+        // remove the old repository group configuration
+        config.removeRepositoryGroup( group );
+       
+        // save repository group configuration
+        group.addRepository( repoId );
+        config.addRepositoryGroup( group );
+       
+        return saveConfiguration( config );
+    }
+    
+    public String removeRepositoryFromGroup()
+    {
+        Configuration config = archivaConfiguration.getConfiguration();
+        RepositoryGroupConfiguration group = config.findRepositoryGroupById( repoGroupId );
+       
+        validateRepository();
+       
+        if( hasErrors() )
+        {
+            return ERROR;
+        }
+       
+        if ( !group.getRepositories().contains( repoId ) )
+        {
+            addActionError( "No repository with id[" + repoId + "] found in the group" );
+            return ERROR;
+        }
+       
+        // remove the old repository group configuration
+        config.removeRepositoryGroup( group );
+       
+        // save repository group configuration
+        group.removeRepository( repoId );
+        config.addRepositoryGroup( group );
+       
+        return saveConfiguration( config );
+    }
+    
+    public void validateRepository()
+    {
+        Configuration config = archivaConfiguration.getConfiguration();
+        RepositoryGroupConfiguration group = config.findRepositoryGroupById( repoGroupId );
+        ManagedRepositoryConfiguration repo = config.findManagedRepositoryById( repoId );
+       
+        if ( group == null )
+        {
+            addActionError( "A repository group with that id does not exist." );
+        }
+       
+        if ( repo == null )
+        {
+            addActionError( "A repository with that id does not exist." );
+        }
+    }
+    
+    public RepositoryGroupConfiguration getRepositoryGroup()
+    {
+        return repositoryGroup;
+    }
+    
+    public void setRepositoryGroup( RepositoryGroupConfiguration repositoryGroup )
+    {
+        this.repositoryGroup = repositoryGroup;
+    }
+    
+    public Map<String, RepositoryGroupConfiguration> getRepositoryGroups()
+    {
+        return repositoryGroups;
+    }
+    
+    public void setRepositoryGroups( Map<String, RepositoryGroupConfiguration> repositoryGroups )
+    {
+        this.repositoryGroups = repositoryGroups;
+    }
+    
+    public Map<String, ManagedRepositoryConfiguration> getManagedRepositories()
+    {
+        return managedRepositories;
+    }
+    
+    public Map<String, List<String>> getGroupToRepositoryMap()
+    {
+        return this.groupToRepositoryMap;
+    }
+    
+    public String getRepoGroupId()
+    {
+        return repoGroupId;
+    }
+    
+    public void setRepoGroupId( String repoGroupId )
+    {
+        this.repoGroupId = repoGroupId;
+    }
+    
+    public String getRepoId()
+    {
+        return repoId;
+    }
+    
+    public void setRepoId( String repoId )
+    {
+        this.repoId = repoId;
+    }
+    
+    public String getBaseUrl()
+    {
+        return baseUrl;
+    }
+}
diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/action/admin/repositories/SortRepositoriesAction.java b/archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/action/admin/repositories/SortRepositoriesAction.java
new file mode 100644 (file)
index 0000000..4ac5c3d
--- /dev/null
@@ -0,0 +1,122 @@
+package org.apache.maven.archiva.web.action.admin.repositories;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.maven.archiva.configuration.Configuration;
+import org.apache.maven.archiva.configuration.RepositoryGroupConfiguration;
+
+/**
+ * SortRepositoriesAction
+ * 
+ * @author
+ * @version
+ * @plexus.component role="com.opensymphony.xwork.Action" role-hint="sortRepositoriesAction"
+ */
+public class SortRepositoriesAction 
+    extends AbstractRepositoriesAdminAction
+{
+    private String repoGroupId;
+       
+    private String targetRepo;
+       
+    public String sortDown()
+    {
+        Configuration config = archivaConfiguration.getConfiguration();
+               
+        List<String> repositories = getRepositoriesFromGroup();
+               
+        int idx = findTargetRepository( repositories, targetRepo );
+               
+        if ( idx >= 0 && validIndex( repositories, idx + 1 ) )
+        {
+            repositories.remove( idx );
+            repositories.add( idx + 1, targetRepo );
+        }
+               
+        return saveConfiguration( config );
+    }
+       
+    public String sortUp()
+    {
+        Configuration config = archivaConfiguration.getConfiguration();
+               
+        List<String> repositories = getRepositoriesFromGroup();
+
+        int idx = findTargetRepository( repositories, targetRepo );
+               
+        if ( idx >= 0 && validIndex( repositories, idx - 1 ) )
+        {
+            repositories.remove( idx );
+            repositories.add( idx - 1, targetRepo );
+        }
+               
+        return saveConfiguration( config );
+    }
+       
+    public String getRepoGroupId()
+    {
+        return repoGroupId;
+    }
+       
+    public void setRepoGroupId( String repoGroupId )
+    {
+        this.repoGroupId = repoGroupId;
+    }
+       
+    public String getTargetRepo()
+    {
+        return targetRepo;
+    }
+       
+    public void setTargetRepo( String targetRepo )
+    {
+        this.targetRepo = targetRepo;
+    }
+       
+    private int findTargetRepository( List<String> repositories, String targetRepository )
+    {
+        int idx = ( -1 );
+               
+        for ( int i = 0; i < repositories.size(); i++ )
+        {
+            if ( StringUtils.equals( targetRepository, repositories.get(i) ) )
+            {
+                idx = i;
+                break;
+            }
+        }
+        return idx;
+    }
+       
+    private List<String> getRepositoriesFromGroup()
+    {
+        Configuration config = archivaConfiguration.getConfiguration();
+        RepositoryGroupConfiguration repoGroup = config.findRepositoryGroupById( repoGroupId );
+        return repoGroup.getRepositories();
+    }
+       
+    private boolean validIndex( List<String> repositories, int idx )
+       {
+           return ( idx >= 0 ) && ( idx < repositories.size() );
+       }
+}
index 24933e253f6822a3af47c0b45a0574f8e73d9999..b8309df613b8ae6ccafe131613a313b49d93f496 100644 (file)
     <action name="index" class="repositoriesAction" method="input">
       <result name="input">/WEB-INF/jsp/admin/repositories.jsp</result>
     </action>
+    
+    <!-- .\ REPOSITORY GROUPS \._______________________________________ -->
+    
+    <action name="repositoryGroups" class="repositoryGroupsAction" method="input">
+      <result name="input">/WEB-INF/jsp/admin/repositoryGroups.jsp</result>
+    </action>
+    
+    <action name="addRepositoryGroup" class="repositoryGroupsAction" method="addRepositoryGroup">
+      <result name="input">/WEB-INF/jsp/admin/repositoryGroups.jsp</result>
+      <result name="error">/WEB-INF/jsp/admin/repositoryGroups.jsp</result>
+      <result name="success" type="redirect-action">repositoryGroups</result>
+      <interceptor-ref name="configuredPrepareParamsStack"/>
+    </action>
+    
+    <action name="confirmDeleteRepositoryGroup" class="deleteRepositoryGroupAction" method="confirmDelete">
+      <result name="input">/WEB-INF/jsp/admin/deleteRepositoryGroup.jsp</result>
+      <interceptor-ref name="configuredPrepareParamsStack"/>
+    </action>
+    
+    <action name="deleteRepositoryGroup" class="deleteRepositoryGroupAction" method="delete">
+      <result name="input">/WEB-INF/jsp/admin/deleteRepositoryGroup.jsp</result>
+      <result name="error">/WEB-INF/jsp/admin/deleteRepositoryGroup.jsp</result>
+      <result name="success" type="redirect-action">repositoryGroups</result>
+      <interceptor-ref name="configuredPrepareParamsStack"/>
+    </action>
+       
+    <action name="addRepositoryToGroup" class="repositoryGroupsAction" method="addRepositoryToGroup">
+      <result name="input">/WEB-INF/jsp/admin/repositoryGroups.jsp</result>
+      <result name="error">/WEB-INF/jsp/admin/repositoryGroups.jsp</result>
+      <result name="success" type="redirect-action">repositoryGroups</result>
+      <interceptor-ref name="configuredPrepareParamsStack"/>
+    </action>
+       
+    <action name="removeRepositoryFromGroup" class="repositoryGroupsAction" method="removeRepositoryFromGroup">
+      <result name="input">/WEB-INF/jsp/admin/repositoryGroups.jsp</result>
+      <result name="error">/WEB-INF/jsp/admin/repositoryGroups.jsp</result>
+      <result name="success" type="redirect-action">repositoryGroups</result>
+      <interceptor-ref name="configuredPrepareParamsStack"/>
+    </action>
+       
+    <action name="sortDownRepositoryFromGroup" class="sortRepositoriesAction" method="sortDown">
+      <result name="input">/WEB-INF/jsp/admin/repositoryGroups.jsp</result>
+      <result name="error">/WEB-INF/jsp/admin/repositoryGroups.jsp</result>
+      <result name="success" type="redirect-action">repositoryGroups</result>
+      <interceptor-ref name="configuredPrepareParamsStack"/>
+    </action>
+       
+    <action name="sortUpRepositoryFromGroup" class="sortRepositoriesAction" method="sortUp">
+      <result name="input">/WEB-INF/jsp/admin/repositoryGroups.jsp</result>
+      <result name="error">/WEB-INF/jsp/admin/repositoryGroups.jsp</result>
+      <result name="success" type="redirect-action">repositoryGroups</result>
+      <interceptor-ref name="configuredPrepareParamsStack"/>
+    </action>
 
     <!-- .\ REPOSITORIES \.____________________________________________ -->
 
diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/WEB-INF/jsp/admin/deleteRepositoryGroup.jsp b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/WEB-INF/jsp/admin/deleteRepositoryGroup.jsp
new file mode 100644 (file)
index 0000000..fa18926
--- /dev/null
@@ -0,0 +1,65 @@
+<%--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements.  See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership.  The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License.  You may obtain a copy of the License at
+  ~
+  ~   http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied.  See the License for the
+  ~ specific language governing permissions and limitations
+  ~ under the License.
+  --%>
+
+<%@ taglib prefix="ww" uri="/webwork" %>
+
+<html>
+<head>
+  <title>Admin: Delete Repository Group</title>
+  <ww:head/>
+</head>
+
+<body>
+
+<h1>Admin: Delete Repository Group</h1>
+
+<ww:actionerror/>
+
+<div id="contentArea">
+
+  <div class="warningbox">
+    <p>
+      <strong>WARNING: This operation can not be undone.</strong>
+    </p>
+  </div>
+  
+  <p>
+    Are you sure you want to delete the following repository group?
+  </p>
+
+  <div class="infobox">
+    <table class="infotable">
+      <tr>
+        <td>ID:</td>
+        <td><code>${repositoryGroup.id}</code></td>
+      </tr>
+    </table>
+  </div>
+
+  <ww:form method="post" action="deleteRepositoryGroup" namespace="/admin" validate="true" theme="simple">
+    <ww:hidden name="repoGroupId"/>
+    <div class="buttons">
+      <ww:submit value="Confirm" method="delete"/>
+      <ww:submit value="Cancel" method="execute"/>
+    </div>
+  </ww:form>
+</div>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/WEB-INF/jsp/admin/repositoryGroups.jsp b/archiva-modules/archiva-web/archiva-webapp/src/main/webapp/WEB-INF/jsp/admin/repositoryGroups.jsp
new file mode 100644 (file)
index 0000000..ebfbacd
--- /dev/null
@@ -0,0 +1,149 @@
+<%--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements.  See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership.  The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License.  You may obtain a copy of the License at
+  ~
+  ~   http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied.  See the License for the
+  ~ specific language governing permissions and limitations
+  ~ under the License.
+  --%>
+
+<%@ taglib prefix="ww" uri="/webwork" %>
+<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
+<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
+<%@ taglib prefix="redback" uri="http://plexus.codehaus.org/redback/taglib-1.0" %>
+<%@ taglib prefix="archiva" uri="http://maven.apache.org/archiva" %>
+
+<html>
+<head>
+  <title>Administration - Repository Groups</title>
+  <ww:head/>
+</head>
+
+<body>
+
+<h1>Administration - Repository Groups</h1>
+
+<c:url var="iconDeleteUrl" value="/images/icons/delete.gif"/>
+<c:url var="iconEditUrl" value="/images/icons/edit.png"/>
+<c:url var="iconCreateUrl" value="/images/icons/create.png"/>
+<c:url var="iconUpUrl" value="/images/icons/up.gif"/>
+<c:url var="iconDownUrl" value="/images/icons/down.gif"/>
+
+<div id="contentArea">
+
+<ww:actionerror/>
+<ww:actionmessage/>
+
+<div align="right">
+  <redback:ifAnyAuthorized permissions="archiva-manage-configuration">
+    <ww:form action="addRepositoryGroup" namespace="/admin">
+      <span class="label">Identifier<span style="color:red">*</span>:</span> 
+      <ww:textfield size="10" label="Identifier" theme="simple" name="repositoryGroup.id"/>
+      <ww:submit value="Add Group" theme="simple" cssClass="button"/>
+    </ww:form>
+  </redback:ifAnyAuthorized>
+</div>
+
+<h2>Repository Groups</h2>
+
+<c:choose>
+<c:when test="${empty(repositoryGroups)}">
+  <strong>No Repository Groups Defined.</strong>
+</c:when>
+<c:otherwise>
+
+<div class="admin">
+
+<c:forEach items="${repositoryGroups}" var="repositoryGroup" varStatus="i">
+
+<div class="repoGroup">
+  <div class="managedRepo">
+    
+    <div style="float:right">
+      <ww:url id="deleteRepositoryGroupUrl" action="confirmDeleteRepositoryGroup">
+        <ww:param name="repoGroupId" value="%{'${repositoryGroup.key}'}" />
+      </ww:url>
+      <ww:a href="%{deleteRepositoryGroupUrl}" cssClass="delete">
+        <img src="${iconDeleteUrl}"/>
+      </ww:a>
+    </div>
+    
+    <img src="<c:url value="/images/archiva-splat-32.gif"/>"/>
+    <p class="id">${repositoryGroup.key}</p>
+  </div>
+
+  <c:if test="${!empty(groupToRepositoryMap[repositoryGroup.key])}">
+  <div class="repos">
+    <ww:form name="form${i}" action="addRepositoryToGroup" namespace="/admin" validate="true">
+      <ww:hidden name="repoGroupId" value="%{'${repositoryGroup.key}'}"/>
+      <ww:select list="groupToRepositoryMap['${repositoryGroup.key}']" name="repoId" theme="simple"/>
+      <ww:submit value="Add Repository" theme="simple" cssClass="button"/>
+    </ww:form>
+  </div>
+  </c:if>
+  
+  <c:forEach items="${repositoryGroup.value.repositories}" var="repository" varStatus="r">
+  
+  <c:choose>
+    <c:when test='${(r.index)%2 eq 0}'>
+      <c:set var="rowColor" value="dark" scope="page"/>
+    </c:when>
+    <c:otherwise>
+      <c:set var="rowColor" value="lite" scope="page"/>
+    </c:otherwise>
+  </c:choose>
+
+  <div class="connector ${rowColor}"> 
+    <div class="controls">
+      <redback:ifAnyAuthorized permissions="archiva-manage-configuration">
+        <ww:url id="sortDownRepositoryUrl" action="sortDownRepositoryFromGroup">
+          <ww:param name="repoGroupId" value="%{'${repositoryGroup.key}'}"/>
+          <ww:param name="targetRepo" value="managedRepositories['${repository}'].id"/>
+        </ww:url>
+        <ww:url id="sortUpRepositoryUrl" action="sortUpRepositoryFromGroup">
+          <ww:param name="repoGroupId" value="%{'${repositoryGroup.key}'}"/>
+          <ww:param name="targetRepo" value="managedRepositories['${repository}'].id"/>
+        </ww:url>
+        <ww:url id="removeRepositoryUrl" action="removeRepositoryFromGroup">
+          <ww:param name="repoGroupId" value="%{'${repositoryGroup.key}'}"/>
+          <ww:param name="repoId" value="managedRepositories['${repository}'].id"/>
+        </ww:url>
+        <ww:a href="%{sortUpRepositoryUrl}" cssClass="up" title="Move Repository Up">
+          <img src="${iconUpUrl}"/>
+        </ww:a>
+        <ww:a href="%{sortDownRepositoryUrl}" cssClass="down" title="Move Repository Down">
+          <img src="${iconDownUrl}"/>
+        </ww:a>
+        <ww:a href="%{removeRepositoryUrl}" cssClass="delete" title="Delete Repository">
+          <img src="${iconDeleteUrl}"/>
+        </ww:a>
+      </redback:ifAnyAuthorized>
+    </div>
+  
+    <h4>Repository</h4>
+    
+    <div class="managedRepo">
+      <img src="<c:url value="/images/archiva-splat-32.gif"/>"/>
+      <p class="id">${repository}</p>
+      <p class="name">${managedRepositories[repository].name}</p>
+      <p class="url"><a href="${baseUrl}/${managedRepositories[repository].id}/">${baseUrl}/${managedRepositories[repository].id}</a></p>
+    </div>
+  </div> <%-- repository --%> 
+  </c:forEach>
+
+</div> <%-- repository group --%>
+</c:forEach>
+</div> <%-- admin --%>
+
+</c:otherwise>
+</c:choose>
\ No newline at end of file
index 679645c80e9129d915646e9a325d9132646ffff2..ad98bb07ea80b0824b4377c391837affe94ff243 100644 (file)
     <redback:ifAuthorized permission="archiva-manage-configuration">
       <h5>Administration</h5>
       <ul>
+        <li class="none">
+          <my:currentWWUrl action="repositoryGroups" namespace="/admin">Repository Groups</my:currentWWUrl>
+        </li>
         <li class="none">
           <my:currentWWUrl action="repositories" namespace="/admin">Repositories</my:currentWWUrl>
         </li>
index 195420b674af9b90b582f743c0b9d843409b8d3a..114580c0fef289ef68a2c7a6a16399bd58ba170a 100644 (file)
@@ -245,14 +245,16 @@ div.repository {
        border-bottom: 1px solid #DFDEDE;
 }
 
-div.proxyConfig {
+div.proxyConfig,
+div.repoGroup {
        border: 1px dashed #DFDEDE;
        margin-bottom: 15px;
        padding: 5px;
 }
 
 div.proxyConfig div.managedRepo,
-div.proxyConfig div.remoteRepo {
+div.proxyConfig div.remoteRepo,
+div.repoGroup div.managedRepo {
     border: 1px dotted gray;
        padding: 5px;
        background-color: white;
@@ -263,7 +265,8 @@ div.proxyConfig div.remoteRepo {
 }
 
 div.proxyConfig div.managedRepo img,
-div.proxyConfig div.remoteRepo img {
+div.proxyConfig div.remoteRepo img,
+div.repoGroup div.managedRepo img {
        float: left;
        border: 0px;
 }
@@ -275,12 +278,20 @@ div.proxyConfig div.remoteRepo p {
        padding: 0px;
 }
 
+div.repoGroup div.managedRepo p {
+    margin: 8px;
+       margin-left: 40px;
+       padding: 0px;
+}
+
 div.proxyConfig div.managedRepo p.id,
-div.proxyConfig div.remoteRepo p.id {
+div.proxyConfig div.remoteRepo p.id,
+div.repoGroup div.managedRepo p.id {
        font-family: monospace;
 }
 
-div.proxyConfig div.connector {
+div.proxyConfig div.connector,
+div.repoGroup div.connector {
        border: 1px solid #aaaaff;
        margin-top: 10px;
        margin-left: 40px !important;
@@ -291,11 +302,13 @@ div.proxyConfig a.expand {
        color: gray;    
 }
 
-div.proxyConfig div.controls {
+div.proxyConfig div.controls,
+div.repoGroup div.controls {
        float: right;
 }
 
-div.proxyConfig div.connector h4 {
+div.proxyConfig div.connector h4,
+div.repoGroup div.connector h4 {
        padding: 3px;
        font-size: 8pt;
        margin: 0px;
@@ -321,6 +334,12 @@ div.proxyConfig div.connector table p {
        margin: 0px;
        padding: 0px;
 }
+
+div.repoGroup div.repos {
+    text-align: right;
+    padding: 4px 0px 0px 0px;
+}
+
 div.admin div.dark,
 div.admin div.lite {
        border: 1px solid #aaaaaa;      
diff --git a/archiva-modules/archiva-web/archiva-webapp/src/test/java/org/apache/maven/archiva/web/action/admin/repositories/DeleteRepositoryGroupActionTest.java b/archiva-modules/archiva-web/archiva-webapp/src/test/java/org/apache/maven/archiva/web/action/admin/repositories/DeleteRepositoryGroupActionTest.java
new file mode 100644 (file)
index 0000000..46efd31
--- /dev/null
@@ -0,0 +1,156 @@
+package org.apache.maven.archiva.web.action.admin.repositories;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Collections;
+
+import com.opensymphony.xwork.Action;
+import org.apache.maven.archiva.configuration.ArchivaConfiguration;
+import org.apache.maven.archiva.configuration.Configuration;
+import org.apache.maven.archiva.configuration.RepositoryGroupConfiguration;
+import org.codehaus.plexus.redback.xwork.interceptor.SecureActionBundle;
+import org.codehaus.plexus.redback.xwork.interceptor.SecureActionException;
+import org.codehaus.plexus.spring.PlexusInSpringTestCase;
+import org.easymock.MockControl;
+
+/**
+ * DeleteRepositoryGroupActionTest
+ * 
+ * @author
+ * @version
+ */
+public class DeleteRepositoryGroupActionTest 
+    extends PlexusInSpringTestCase
+{
+    private static final String REPO_GROUP_ID = "repo-group-ident";
+
+    private DeleteRepositoryGroupAction action;
+
+    private MockControl archivaConfigurationControl;
+
+    private ArchivaConfiguration archivaConfiguration;
+
+    protected void setUp()
+        throws Exception
+    {
+        super.setUp();
+        
+        action = (DeleteRepositoryGroupAction) lookup ( Action.class.getName(), "deleteRepositoryGroupAction" );
+        
+        archivaConfigurationControl = MockControl.createControl( ArchivaConfiguration.class );
+        archivaConfiguration = (ArchivaConfiguration) archivaConfigurationControl.getMock();
+        action.setArchivaConfiguration( archivaConfiguration );
+    }
+    
+    public void testSecureActionBundle()
+        throws SecureActionException
+       {
+        archivaConfiguration.getConfiguration();
+        archivaConfigurationControl.setReturnValue( new Configuration() );
+        archivaConfigurationControl.replay();
+       
+        action.prepare();
+        SecureActionBundle bundle = action.getSecureActionBundle();
+        assertTrue( bundle.requiresAuthentication() );
+        assertEquals( 1, bundle.getAuthorizationTuples().size() );
+    }
+
+    public void testDeleteRepositoryGroupConfirmation()
+        throws Exception
+    {
+        RepositoryGroupConfiguration origRepoGroup = createRepositoryGroup();
+        Configuration configuration = createConfigurationForEditing( origRepoGroup );
+    
+        archivaConfiguration.getConfiguration();
+        archivaConfigurationControl.setReturnValue( configuration );
+        archivaConfigurationControl.replay();
+        
+        action.setRepoGroupId( REPO_GROUP_ID );
+
+        action.prepare();
+        assertEquals( REPO_GROUP_ID, action.getRepoGroupId() );
+        RepositoryGroupConfiguration repoGroup = action.getRepositoryGroup();
+        assertNotNull( repoGroup );
+        assertEquals( repoGroup.getId(), action.getRepoGroupId() );
+        assertEquals( Collections.singletonList( origRepoGroup ), configuration.getRepositoryGroups() );
+    }
+
+    public void testDeleteRepositoryGroup()
+        throws Exception
+    {
+        Configuration configuration = createConfigurationForEditing( createRepositoryGroup() );
+       
+        archivaConfiguration.getConfiguration();
+        archivaConfigurationControl.setReturnValue( configuration, 3 );
+        archivaConfiguration.save( configuration );
+        archivaConfigurationControl.replay();
+       
+        action.setRepoGroupId( REPO_GROUP_ID );
+       
+        action.prepare();
+        assertEquals( REPO_GROUP_ID, action.getRepoGroupId() );
+        RepositoryGroupConfiguration repoGroup = action.getRepositoryGroup();
+        assertNotNull( repoGroup );
+        assertEquals( Collections.singletonList( repoGroup ), configuration.getRepositoryGroups() );
+       
+        String status = action.delete();
+        assertEquals( Action.SUCCESS, status );
+        assertTrue( configuration.getRepositoryGroups().isEmpty() );
+    }
+
+    public void testDeleteRepositoryGroupCancelled()
+        throws Exception
+    {
+        RepositoryGroupConfiguration origRepoGroup = createRepositoryGroup();
+        Configuration configuration = createConfigurationForEditing ( origRepoGroup );
+       
+        archivaConfiguration.getConfiguration();
+        archivaConfigurationControl.setReturnValue( configuration, 2 );
+
+        archivaConfiguration.save( configuration );
+        archivaConfigurationControl.replay();
+        
+        action.setRepoGroupId( REPO_GROUP_ID );
+        
+        action.prepare();
+        assertEquals( REPO_GROUP_ID, action.getRepoGroupId() );
+        RepositoryGroupConfiguration repoGroup = action.getRepositoryGroup();
+        assertNotNull( repoGroup );
+        
+        String status = action.execute();
+        assertEquals( Action.SUCCESS, status );
+        assertEquals( Collections.singletonList( repoGroup ), configuration.getRepositoryGroups() );
+    }
+
+    private Configuration createConfigurationForEditing( RepositoryGroupConfiguration repoGroup )
+    {
+        Configuration configuration = new Configuration();
+        configuration.addRepositoryGroup( repoGroup );
+        return configuration;
+    }
+    
+    private RepositoryGroupConfiguration createRepositoryGroup()
+    {
+        RepositoryGroupConfiguration repoGroup = new RepositoryGroupConfiguration();
+        repoGroup.setId( REPO_GROUP_ID );
+       
+        return repoGroup;
+    }
+}
diff --git a/archiva-modules/archiva-web/archiva-webapp/src/test/java/org/apache/maven/archiva/web/action/admin/repositories/RepositoryGroupsActionTest.java b/archiva-modules/archiva-web/archiva-webapp/src/test/java/org/apache/maven/archiva/web/action/admin/repositories/RepositoryGroupsActionTest.java
new file mode 100644 (file)
index 0000000..5b12e8e
--- /dev/null
@@ -0,0 +1,380 @@
+package org.apache.maven.archiva.web.action.admin.repositories;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Collections;
+
+import org.apache.maven.archiva.configuration.ArchivaConfiguration;
+import org.apache.maven.archiva.configuration.Configuration;
+import org.apache.maven.archiva.configuration.ManagedRepositoryConfiguration;
+import org.apache.maven.archiva.configuration.RepositoryGroupConfiguration;
+import org.codehaus.plexus.redback.xwork.interceptor.SecureActionBundle;
+import org.codehaus.plexus.redback.xwork.interceptor.SecureActionException;
+import org.codehaus.plexus.spring.PlexusInSpringTestCase;
+import org.easymock.MockControl;
+
+import com.meterware.servletunit.ServletRunner;
+import com.meterware.servletunit.ServletUnitClient;
+import com.opensymphony.xwork.Action;
+
+/**
+ * RepositoryGroupsActionTest
+ * 
+ * @author
+ * @version
+ */
+public class RepositoryGroupsActionTest 
+    extends PlexusInSpringTestCase
+{
+    private static final String REPO_GROUP_ID = "repo-group-ident";
+       
+    private static final String REPO1_ID = "managed-repo-ident-1";
+       
+    private static final String REPO2_ID = "managed-repo-ident-2";
+       
+    private RepositoryGroupsAction action;
+       
+    private MockControl archivaConfigurationControl;
+
+    private ArchivaConfiguration archivaConfiguration;
+
+    protected void setUp()
+        throws Exception
+    {
+        super.setUp();
+       
+        action = (RepositoryGroupsAction) lookup( Action.class.getName(), "repositoryGroupsAction" );
+           
+        archivaConfigurationControl = MockControl.createControl( ArchivaConfiguration.class );
+        archivaConfiguration = (ArchivaConfiguration) archivaConfigurationControl.getMock();
+        action.setArchivaConfiguration( archivaConfiguration );
+    }
+
+    public void testSecureActionBundle()
+        throws SecureActionException
+    {
+        archivaConfiguration.getConfiguration();
+        archivaConfigurationControl.setReturnValue( new Configuration() );
+        archivaConfigurationControl.replay();
+       
+        action.prepare();
+        SecureActionBundle bundle = action.getSecureActionBundle();
+        assertTrue( bundle.requiresAuthentication() );
+        assertEquals( 1, bundle.getAuthorizationTuples().size() );
+    }
+
+    public void testAddRepositoryGroup()
+        throws Exception
+    {
+        Configuration configuration = new Configuration();
+        archivaConfiguration.getConfiguration();
+        archivaConfigurationControl.setReturnValue( configuration, 2 );
+       
+        archivaConfiguration.save( configuration );
+        archivaConfigurationControl.replay();
+       
+        action.prepare();
+        RepositoryGroupConfiguration repositoryGroup = action.getRepositoryGroup();
+        repositoryGroup.setId( REPO_GROUP_ID );
+       
+        String status = action.addRepositoryGroup();
+        assertEquals( Action.SUCCESS, status );
+       
+        assertEquals( Collections.singletonList( repositoryGroup ), configuration.getRepositoryGroups() );
+       
+        archivaConfigurationControl.verify();
+    }
+       
+    public void testAddEmptyRepositoryGroup()
+        throws Exception
+    {
+        Configuration configuration = new Configuration();
+        archivaConfiguration.getConfiguration();
+        archivaConfigurationControl.setReturnValue( configuration, 2 );
+       
+        archivaConfiguration.save( configuration );
+       
+        archivaConfigurationControl.replay();
+       
+        action.prepare();
+           
+        String status = action.addRepositoryGroup();
+        assertEquals( Action.ERROR, status );
+           
+        assertEquals( 0, configuration.getRepositoryGroups().size() );
+    }
+       
+    public void testAddDuplicateRepositoryGroup()
+        throws Exception
+    {
+        Configuration configuration = new Configuration();
+        archivaConfiguration.getConfiguration();
+        archivaConfigurationControl.setReturnValue( configuration, 3 );
+
+        archivaConfiguration.save( configuration );
+       
+        archivaConfigurationControl.replay();
+       
+        action.prepare();
+        RepositoryGroupConfiguration repositoryGroup = action.getRepositoryGroup();
+        repositoryGroup.setId( REPO_GROUP_ID );
+       
+        String status = action.addRepositoryGroup();
+        assertEquals( Action.SUCCESS, status );
+       
+        assertEquals( Collections.singletonList( repositoryGroup ), configuration.getRepositoryGroups() );
+                   
+        repositoryGroup.setId( REPO_GROUP_ID );
+        status = action.addRepositoryGroup();
+           
+        assertEquals( Action.ERROR, status );
+        assertEquals( Collections.singletonList( repositoryGroup ), configuration.getRepositoryGroups() );
+    }
+
+    public void testGetRepositoryGroups()
+        throws Exception
+    {
+        ServletRunner sr = new ServletRunner();
+        ServletUnitClient sc = sr.newClient();
+
+        Configuration configuration = createInitialConfiguration();
+        
+        archivaConfiguration.getConfiguration();
+        archivaConfigurationControl.setReturnValue( configuration );
+        archivaConfigurationControl.replay();
+        
+        action.setServletRequest( sc.newInvocation( "http://localhost/admin/repositoryGroups.action" ).getRequest() );
+        action.prepare();
+        String result = action.execute();
+        assertEquals( Action.SUCCESS, result );
+        
+        assertEquals( "http://localhost:0/repository", action.getBaseUrl() );
+        
+        assertNotNull( action.getRepositoryGroups() );
+        assertEquals( 1, action.getRepositoryGroups().size() );
+        assertEquals( 2, action.getManagedRepositories().size() );
+        
+        RepositoryGroupConfiguration repoGroup = action.getRepositoryGroups().get( REPO_GROUP_ID );
+        
+        assertEquals( 1, repoGroup.getRepositories().size() );
+        assertEquals( REPO1_ID, repoGroup.getRepositories().get( 0 ) );
+        assertNotNull( action.getGroupToRepositoryMap() );
+        assertEquals( 1, action.getGroupToRepositoryMap().size() );
+        
+        java.util.List repos = action.getGroupToRepositoryMap().get( repoGroup.getId() );
+        assertEquals( 1, repos.size() );
+        assertEquals( REPO2_ID, repos.get( 0 ) );
+    }
+       
+    public void testAddRepositoryToGroup()
+        throws Exception
+    {
+        Configuration configuration = createInitialConfiguration();
+        
+        archivaConfiguration.getConfiguration();
+        archivaConfigurationControl.setReturnValue( configuration, 6 );
+        archivaConfiguration.save( configuration );
+        archivaConfigurationControl.replay();
+        
+        action.prepare();
+        String result = action.execute();
+        assertEquals( Action.SUCCESS, result );
+        
+        assertNotNull( action.getRepositoryGroups() );
+        assertEquals( 1, action.getRepositoryGroups().size() );
+        assertEquals( 2, action.getManagedRepositories().size() );
+        
+        RepositoryGroupConfiguration repoGroup = action.getRepositoryGroups().get( REPO_GROUP_ID );
+        assertEquals( 1 , repoGroup.getRepositories().size() );
+        assertEquals( REPO1_ID, repoGroup.getRepositories().get( 0 ) );
+        
+        assertNotNull( action.getGroupToRepositoryMap() );
+        assertEquals( 1, action.getGroupToRepositoryMap().size() );
+        
+        java.util.List repos = action.getGroupToRepositoryMap().get( repoGroup.getId() );
+        assertEquals( 1, repos.size() );
+        assertEquals( REPO2_ID, repos.get( 0 ) );
+        
+        action.setRepoGroupId( REPO_GROUP_ID );
+        action.setRepoId( REPO2_ID );
+        
+        result = action.addRepositoryToGroup();
+        assertEquals( Action.SUCCESS, result );
+        
+        action.prepare();
+        result = action.execute();
+        assertEquals( Action.SUCCESS, result );
+     
+        assertEquals( 1, action.getRepositoryGroups().size() );
+        repoGroup = action.getRepositoryGroups().get( REPO_GROUP_ID );
+        assertEquals( 2, repoGroup.getRepositories().size() );
+        assertEquals( REPO1_ID, repoGroup.getRepositories().get( 0 ) );
+        assertEquals( REPO2_ID, repoGroup.getRepositories().get( 1 ) );
+        
+        assertEquals( 0, action.getGroupToRepositoryMap().size() );
+        assertNull( action.getGroupToRepositoryMap().get( repoGroup.getId() ) );
+    }
+
+    public void testRemoveRepositoryFromGroup()
+        throws Exception
+    {
+        Configuration configuration = createInitialConfiguration();
+        
+        archivaConfiguration.getConfiguration();
+        archivaConfigurationControl.setReturnValue( configuration, 6 );
+        archivaConfiguration.save( configuration );
+        archivaConfigurationControl.replay();
+        
+        action.prepare();
+        String result = action.execute();
+        assertEquals( Action.SUCCESS, result );
+        
+        assertNotNull( action.getRepositoryGroups() );
+        assertEquals( 1, action.getRepositoryGroups().size() );
+        assertEquals( 2, action.getManagedRepositories().size() );
+        
+        RepositoryGroupConfiguration repoGroup = action.getRepositoryGroups().get( REPO_GROUP_ID );
+        assertEquals( 1 , repoGroup.getRepositories().size() );
+        assertEquals( REPO1_ID, repoGroup.getRepositories().get( 0 ) );
+        
+        assertNotNull( action.getGroupToRepositoryMap() );
+        assertEquals( 1, action.getGroupToRepositoryMap().size() );
+        
+        java.util.List repos = action.getGroupToRepositoryMap().get( repoGroup.getId() );
+        assertEquals( 1, repos.size() );
+        assertEquals( REPO2_ID, repos.get( 0 ) );
+        
+        action.setRepoGroupId( REPO_GROUP_ID );
+        action.setRepoId( REPO1_ID );
+        
+        result = action.removeRepositoryFromGroup();
+        assertEquals( Action.SUCCESS, result );
+        
+        action.prepare();
+        result = action.execute();
+        assertEquals( Action.SUCCESS, result );
+        
+        repoGroup = action.getRepositoryGroups().get( REPO_GROUP_ID );
+        assertEquals( 0, repoGroup.getRepositories().size() );
+        
+        assertNotNull( action.getGroupToRepositoryMap() );
+        assertEquals( 1, action.getGroupToRepositoryMap().size() );
+        
+        repos = action.getGroupToRepositoryMap().get( repoGroup.getId() );
+        assertEquals( 2, repos.size() );
+        assertEquals( REPO1_ID, repos.get( 0 ) );
+        assertEquals( REPO2_ID, repos.get( 1 ) );
+    }
+
+    public void testAddDuplicateRepositoryToGroup()
+        throws Exception
+    {
+        Configuration configuration = createInitialConfiguration();
+        
+        archivaConfiguration.getConfiguration();
+        archivaConfigurationControl.setReturnValue( configuration, 6 );
+        archivaConfiguration.save( configuration );
+        archivaConfigurationControl.replay();
+        
+        action.prepare();
+        String result = action.execute();
+        assertEquals( Action.SUCCESS, result );
+        
+        assertNotNull( action.getRepositoryGroups() );
+        assertEquals( 1, action.getRepositoryGroups().size() );
+        assertEquals( 2, action.getManagedRepositories().size() );
+        
+        RepositoryGroupConfiguration repoGroup = action.getRepositoryGroups().get( REPO_GROUP_ID );
+        assertEquals( 1 , repoGroup.getRepositories().size() );
+        assertEquals( REPO1_ID, repoGroup.getRepositories().get( 0 ) );
+        
+        assertNotNull( action.getGroupToRepositoryMap() );
+        assertEquals( 1, action.getGroupToRepositoryMap().size() );
+        
+        java.util.List repos = action.getGroupToRepositoryMap().get( repoGroup.getId() );
+        assertEquals( 1, repos.size() );
+        assertEquals( REPO2_ID, repos.get( 0 ) );
+        
+        action.setRepoGroupId( REPO_GROUP_ID );
+        action.setRepoId( REPO1_ID );
+        
+        result = action.addRepositoryToGroup();
+        assertEquals( Action.ERROR, result );
+    }
+       
+    public void testRemoveRepositoryNotInGroup()
+        throws Exception
+    {
+        Configuration configuration = createInitialConfiguration();
+        
+        archivaConfiguration.getConfiguration();
+        archivaConfigurationControl.setReturnValue( configuration, 6 );
+        archivaConfiguration.save( configuration );
+        archivaConfigurationControl.replay();
+        
+        action.prepare();
+        String result = action.execute();
+        assertEquals( Action.SUCCESS, result );
+        
+        assertNotNull( action.getRepositoryGroups() );
+        assertEquals( 1, action.getRepositoryGroups().size() );
+        assertEquals( 2, action.getManagedRepositories().size() );
+        
+        RepositoryGroupConfiguration repoGroup = action.getRepositoryGroups().get( REPO_GROUP_ID );
+        assertEquals( 1 , repoGroup.getRepositories().size() );
+        assertEquals( REPO1_ID, repoGroup.getRepositories().get( 0 ) );
+        
+        assertNotNull( action.getGroupToRepositoryMap() );
+        assertEquals( 1, action.getGroupToRepositoryMap().size() );
+        
+        java.util.List repos = action.getGroupToRepositoryMap().get( repoGroup.getId() );
+        assertEquals( 1, repos.size() );
+        assertEquals( REPO2_ID, repos.get( 0 ) );
+        
+        action.setRepoGroupId( REPO_GROUP_ID );
+        action.setRepoId( REPO2_ID );
+        
+        result = action.removeRepositoryFromGroup();
+        assertEquals( Action.ERROR, result );
+    }
+
+    private Configuration createInitialConfiguration()
+    {
+        Configuration config = new Configuration();
+               
+        ManagedRepositoryConfiguration managedRepo1 = new ManagedRepositoryConfiguration();
+        managedRepo1.setId( REPO1_ID );
+        
+        config.addManagedRepository( managedRepo1 );
+        
+        ManagedRepositoryConfiguration managedRepo2 = new ManagedRepositoryConfiguration();
+        managedRepo2.setId( REPO2_ID );
+        
+        config.addManagedRepository( managedRepo2 );
+        
+        RepositoryGroupConfiguration repoGroup = new RepositoryGroupConfiguration();
+        repoGroup.setId( REPO_GROUP_ID );
+        repoGroup.addRepository( REPO1_ID );
+               
+        config.addRepositoryGroup( repoGroup );
+               
+        return config;
+    }
+}
diff --git a/archiva-modules/archiva-web/archiva-webapp/src/test/java/org/apache/maven/archiva/web/action/admin/repositories/SortRepositoriesActionTest.java b/archiva-modules/archiva-web/archiva-webapp/src/test/java/org/apache/maven/archiva/web/action/admin/repositories/SortRepositoriesActionTest.java
new file mode 100644 (file)
index 0000000..9cd3606
--- /dev/null
@@ -0,0 +1,225 @@
+package org.apache.maven.archiva.web.action.admin.repositories;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.archiva.configuration.ArchivaConfiguration;
+import org.apache.maven.archiva.configuration.Configuration;
+import org.apache.maven.archiva.configuration.RepositoryGroupConfiguration;
+import org.codehaus.plexus.redback.xwork.interceptor.SecureActionBundle;
+import org.codehaus.plexus.redback.xwork.interceptor.SecureActionException;
+import org.codehaus.plexus.spring.PlexusInSpringTestCase;
+import org.easymock.MockControl;
+
+import com.opensymphony.xwork.Action;
+
+/**
+ * SortRepositoriesActionTest
+ * 
+ * @author
+ * @version
+ */
+public class SortRepositoriesActionTest 
+    extends PlexusInSpringTestCase
+{
+    private static final String REPO_GROUP_ID = "repo-group-ident";
+       
+    private static final String REPO1_ID = "managed-repo-ident-1";
+       
+    private static final String REPO2_ID = "managed-repo-ident-2";
+       
+    private static final String REPO3_ID = "managed-repo-ident-3";
+       
+    private MockControl archivaConfigurationControl;
+
+    private ArchivaConfiguration archivaConfiguration;
+    
+    private SortRepositoriesAction action;
+    
+    protected void setUp()
+        throws Exception
+    {
+        super.setUp();
+           
+        action = (SortRepositoriesAction) lookup( Action.class.getName(), "sortRepositoriesAction" );
+           
+        archivaConfigurationControl = MockControl.createControl( ArchivaConfiguration.class );
+        archivaConfiguration = (ArchivaConfiguration) archivaConfigurationControl.getMock();
+        action.setArchivaConfiguration( archivaConfiguration );
+    }
+    
+    public void testSecureActionBundle()
+        throws SecureActionException
+    {
+        archivaConfiguration.getConfiguration();
+        archivaConfigurationControl.setReturnValue( new Configuration() );
+        archivaConfigurationControl.replay();
+       
+        SecureActionBundle bundle = action.getSecureActionBundle();
+        assertTrue( bundle.requiresAuthentication() );
+        assertEquals( 1, bundle.getAuthorizationTuples().size() );
+    }
+    
+    public void testSortDownFirstRepository()
+        throws Exception
+    {
+        Configuration configuration = createInitialConfiguration();
+        
+        archivaConfiguration.getConfiguration();
+        archivaConfigurationControl.setReturnValue( configuration, 4 );
+        archivaConfiguration.save( configuration );
+        archivaConfigurationControl.replay();
+       
+        RepositoryGroupConfiguration repoGroup = (RepositoryGroupConfiguration) configuration.getRepositoryGroups().get( 0 );
+        java.util.List<String> repositories = repoGroup.getRepositories();
+       
+        assertEquals( 3, repositories.size() );
+        assertEquals( REPO1_ID, repositories.get( 0 ) );
+        assertEquals( REPO2_ID, repositories.get( 1 ) );
+        assertEquals( REPO3_ID, repositories.get( 2 ) );
+       
+        // sort down first repo
+        action.setRepoGroupId( repoGroup.getId() );
+        action.setTargetRepo( REPO1_ID );
+       
+        String result = action.sortDown();
+        assertEquals( Action.SUCCESS, result );
+       
+        repoGroup = (RepositoryGroupConfiguration) configuration.getRepositoryGroups().get( 0 );
+        repositories = repoGroup.getRepositories();
+        assertEquals( 3, repositories.size() );
+        assertEquals( REPO2_ID, repositories.get( 0 ) );
+        assertEquals( REPO1_ID, repositories.get( 1 ) );
+        assertEquals( REPO3_ID, repositories.get( 2 ) );
+    }
+    
+    public void testSortDownLastRepository()
+        throws Exception
+    {
+        Configuration configuration = createInitialConfiguration();
+        
+        archivaConfiguration.getConfiguration();
+        archivaConfigurationControl.setReturnValue( configuration, 4 );
+        archivaConfiguration.save( configuration );
+        archivaConfigurationControl.replay();
+       
+        RepositoryGroupConfiguration repoGroup = (RepositoryGroupConfiguration) configuration.getRepositoryGroups().get( 0 );
+        java.util.List<String> repositories = repoGroup.getRepositories();
+        
+        assertEquals( 3, repositories.size() );
+        assertEquals( REPO1_ID, repositories.get( 0 ) );
+        assertEquals( REPO2_ID, repositories.get( 1 ) );
+        assertEquals( REPO3_ID, repositories.get( 2 ) );
+       
+        // sort down last repo
+        action.setRepoGroupId( repoGroup.getId() );
+        action.setTargetRepo( REPO3_ID );
+       
+        String result = action.sortDown();
+        assertEquals( Action.SUCCESS, result );
+       
+        repoGroup = (RepositoryGroupConfiguration) configuration.getRepositoryGroups().get( 0 );
+        repositories = repoGroup.getRepositories();
+        assertEquals( 3, repositories.size() );
+        assertEquals( REPO1_ID, repositories.get( 0 ) );
+        assertEquals( REPO2_ID, repositories.get( 1 ) );
+        assertEquals( REPO3_ID, repositories.get( 2 ) );
+    }
+    
+    public void testSortUpLastRepository()
+        throws Exception
+    {
+        Configuration configuration = createInitialConfiguration();
+        
+        archivaConfiguration.getConfiguration();
+        archivaConfigurationControl.setReturnValue( configuration, 4 );
+        archivaConfiguration.save( configuration );
+        archivaConfigurationControl.replay();
+       
+        RepositoryGroupConfiguration repoGroup = (RepositoryGroupConfiguration) configuration.getRepositoryGroups().get( 0 );
+        java.util.List<String> repositories = repoGroup.getRepositories();
+       
+        assertEquals( 3, repositories.size() );
+        assertEquals( REPO1_ID, repositories.get( 0 ) );
+        assertEquals( REPO2_ID, repositories.get( 1 ) );
+        assertEquals( REPO3_ID, repositories.get( 2 ) );
+       
+        // sort up last repo
+        action.setRepoGroupId( repoGroup.getId() );
+        action.setTargetRepo( REPO3_ID );
+       
+        String result = action.sortUp();
+        assertEquals( Action.SUCCESS, result );
+       
+        repoGroup = (RepositoryGroupConfiguration) configuration.getRepositoryGroups().get( 0 );
+        repositories = repoGroup.getRepositories();
+        assertEquals( 3, repositories.size() );
+        assertEquals( REPO1_ID, repositories.get( 0 ) );
+        assertEquals( REPO3_ID, repositories.get( 1 ) );
+        assertEquals( REPO2_ID, repositories.get( 2 ) );
+    }
+    
+    public void testSortUpFirstRepository()
+        throws Exception
+    {
+        Configuration configuration = createInitialConfiguration();
+        
+        archivaConfiguration.getConfiguration();
+        archivaConfigurationControl.setReturnValue( configuration, 4 );
+        archivaConfiguration.save( configuration );
+        archivaConfigurationControl.replay();
+       
+        RepositoryGroupConfiguration repoGroup = (RepositoryGroupConfiguration) configuration.getRepositoryGroups().get( 0 );
+        java.util.List<String> repositories = repoGroup.getRepositories();
+        
+        assertEquals( 3, repositories.size() );
+        assertEquals( REPO1_ID, repositories.get( 0 ) );
+        assertEquals( REPO2_ID, repositories.get( 1 ) );
+        assertEquals( REPO3_ID, repositories.get( 2 ) );
+        
+        // sort up first repo
+        action.setRepoGroupId( repoGroup.getId() );
+        action.setTargetRepo( REPO1_ID );
+       
+        String result = action.sortUp();
+        assertEquals( Action.SUCCESS, result );
+        
+        repoGroup = (RepositoryGroupConfiguration) configuration.getRepositoryGroups().get( 0 );
+        repositories = repoGroup.getRepositories();
+        assertEquals( 3, repositories.size() );
+        assertEquals( REPO1_ID, repositories.get( 0 ) );
+        assertEquals( REPO2_ID, repositories.get( 1 ) );
+        assertEquals( REPO3_ID, repositories.get( 2 ) );
+    }
+    
+    private Configuration createInitialConfiguration()
+    {
+        Configuration config = new Configuration();
+        
+        RepositoryGroupConfiguration repoGroup = new RepositoryGroupConfiguration();
+        repoGroup.setId( REPO_GROUP_ID );
+        repoGroup.addRepository( REPO1_ID );
+        repoGroup.addRepository( REPO2_ID );
+        repoGroup.addRepository( REPO3_ID );
+               
+        config.addRepositoryGroup( repoGroup );
+        
+        return config;
+    }
+}