001    package org.apache.archiva.admin.repository;
002    /*
003     * Licensed to the Apache Software Foundation (ASF) under one
004     * or more contributor license agreements.  See the NOTICE file
005     * distributed with this work for additional information
006     * regarding copyright ownership.  The ASF licenses this file
007     * to you under the Apache License, Version 2.0 (the
008     * "License"); you may not use this file except in compliance
009     * with the License.  You may obtain a copy of the License at
010     *
011     *   http://www.apache.org/licenses/LICENSE-2.0
012     *
013     * Unless required by applicable law or agreed to in writing,
014     * software distributed under the License is distributed on an
015     * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
016     * KIND, either express or implied.  See the License for the
017     * specific language governing permissions and limitations
018     * under the License.
019     */
020    
021    import org.apache.archiva.admin.model.RepositoryAdminException;
022    import org.apache.archiva.admin.model.RepositoryCommonValidator;
023    import org.apache.archiva.admin.model.beans.AbstractRepository;
024    import org.apache.archiva.admin.model.beans.ManagedRepository;
025    import org.apache.archiva.admin.model.managed.ManagedRepositoryAdmin;
026    import org.apache.archiva.configuration.ArchivaConfiguration;
027    import org.apache.archiva.configuration.Configuration;
028    import org.apache.archiva.redback.components.scheduler.CronExpressionValidator;
029    import org.apache.commons.lang.StringUtils;
030    import org.apache.commons.validator.GenericValidator;
031    import org.apache.archiva.redback.components.registry.Registry;
032    import org.springframework.stereotype.Service;
033    
034    import javax.inject.Inject;
035    import javax.inject.Named;
036    
037    /**
038     * apply basic repository validation : id and name.
039     * Check if already exists.
040     *
041     * @author Olivier Lamy
042     * @since 1.4-M1
043     */
044    @Service
045    public class DefaultRepositoryCommonValidator
046        implements RepositoryCommonValidator
047    {
048    
049        @Inject
050        private ArchivaConfiguration archivaConfiguration;
051    
052        @Inject
053        @Named( value = "commons-configuration" )
054        private org.apache.archiva.redback.components.registry.Registry registry;
055    
056        /**
057         * @param abstractRepository
058         * @param update             in update mode if yes already exists won't be check
059         * @throws RepositoryAdminException
060         */
061        public void basicValidation( AbstractRepository abstractRepository, boolean update )
062            throws RepositoryAdminException
063        {
064            Configuration config = archivaConfiguration.getConfiguration();
065    
066            String repoId = abstractRepository.getId();
067    
068            if ( !update )
069            {
070    
071                if ( config.getManagedRepositoriesAsMap().containsKey( repoId ) )
072                {
073                    throw new RepositoryAdminException( "Unable to add new repository with id [" + repoId
074                                                            + "], that id already exists as a managed repository." );
075                }
076                else if ( config.getRepositoryGroupsAsMap().containsKey( repoId ) )
077                {
078                    throw new RepositoryAdminException( "Unable to add new repository with id [" + repoId
079                                                            + "], that id already exists as a repository group." );
080                }
081                else if ( config.getRemoteRepositoriesAsMap().containsKey( repoId ) )
082                {
083                    throw new RepositoryAdminException( "Unable to add new repository with id [" + repoId
084                                                            + "], that id already exists as a remote repository." );
085                }
086            }
087    
088            if ( StringUtils.isBlank( repoId ) )
089            {
090                throw new RepositoryAdminException( "Repository ID cannot be empty." );
091            }
092    
093            if ( !GenericValidator.matchRegexp( repoId, REPOSITORY_ID_VALID_EXPRESSION ) )
094            {
095                throw new RepositoryAdminException(
096                    "Invalid repository ID. Identifier must only contain alphanumeric characters, underscores(_), dots(.), and dashes(-)." );
097            }
098    
099            String name = abstractRepository.getName();
100    
101            if ( StringUtils.isBlank( name ) )
102            {
103                throw new RepositoryAdminException( "repository name cannot be empty" );
104            }
105    
106            if ( !GenericValidator.matchRegexp( name, REPOSITORY_NAME_VALID_EXPRESSION ) )
107            {
108                throw new RepositoryAdminException(
109                    "Invalid repository name. Repository Name must only contain alphanumeric characters, white-spaces(' '), "
110                        + "forward-slashes(/), open-parenthesis('('), close-parenthesis(')'),  underscores(_), dots(.), and dashes(-)." );
111            }
112    
113        }
114    
115        /**
116         * validate cronExpression and location format
117         *
118         * @param managedRepository
119         * @since 1.4-M2
120         */
121        public void validateManagedRepository( ManagedRepository managedRepository )
122            throws RepositoryAdminException
123        {
124            String cronExpression = managedRepository.getCronExpression();
125            // FIXME : olamy can be empty to avoid scheduled scan ?
126            if ( StringUtils.isNotBlank( cronExpression ) )
127            {
128                CronExpressionValidator validator = new CronExpressionValidator();
129    
130                if ( !validator.validate( cronExpression ) )
131                {
132                    throw new RepositoryAdminException( "Invalid cron expression.", "cronExpression" );
133                }
134            }
135            else
136            {
137                throw new RepositoryAdminException( "Cron expression cannot be empty." );
138            }
139    
140            String repoLocation = removeExpressions( managedRepository.getLocation() );
141    
142            if ( !GenericValidator.matchRegexp( repoLocation,
143                                                ManagedRepositoryAdmin.REPOSITORY_LOCATION_VALID_EXPRESSION ) )
144            {
145                throw new RepositoryAdminException(
146                    "Invalid repository location. Directory must only contain alphanumeric characters, equals(=), question-marks(?), "
147                        + "exclamation-points(!), ampersands(&), forward-slashes(/), back-slashes(\\), underscores(_), dots(.), colons(:), tildes(~), and dashes(-).",
148                    "location" );
149            }
150        }
151    
152        /**
153         * replace some interpolations ${appserver.base} with correct values
154         *
155         * @param directory
156         * @return
157         */
158        public String removeExpressions( String directory )
159        {
160            String value = StringUtils.replace( directory, "${appserver.base}",
161                                                getRegistry().getString( "appserver.base", "${appserver.base}" ) );
162            value = StringUtils.replace( value, "${appserver.home}",
163                                         getRegistry().getString( "appserver.home", "${appserver.home}" ) );
164            return value;
165        }
166    
167        public ArchivaConfiguration getArchivaConfiguration()
168        {
169            return archivaConfiguration;
170        }
171    
172        public void setArchivaConfiguration( ArchivaConfiguration archivaConfiguration )
173        {
174            this.archivaConfiguration = archivaConfiguration;
175        }
176    
177        public Registry getRegistry()
178        {
179            return registry;
180        }
181    
182        public void setRegistry( org.apache.archiva.redback.components.registry.Registry registry )
183        {
184            this.registry = registry;
185        }
186    }