/* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed 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. */ package org.guvnor.structure.backend.repositories; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.annotation.PostConstruct; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.event.Observes; import javax.inject.Inject; import javax.inject.Named; import org.guvnor.structure.config.SystemRepositoryChangedEvent; import org.guvnor.structure.repositories.NewBranchEvent; import org.guvnor.structure.repositories.Repository; import org.guvnor.structure.repositories.impl.git.GitRepository; import org.guvnor.structure.server.config.ConfigGroup; import org.guvnor.structure.server.config.ConfigurationService; import org.guvnor.structure.server.repositories.RepositoryFactory; import org.uberfire.backend.vfs.Path; import org.uberfire.java.nio.file.FileSystem; import static org.guvnor.structure.server.config.ConfigType.*; import static org.uberfire.backend.server.util.Paths.*; /** * Cache for configured repositories. */ @ApplicationScoped public class ConfiguredRepositories { private ConfigurationService configurationService; private RepositoryFactory repositoryFactory; private Repository systemRepository; private Map<String, Repository> repositoriesByAlias = new HashMap<>(); private Map<Path, Repository> repositoriesByBranchRoot = new HashMap<>(); public ConfiguredRepositories() { } @Inject public ConfiguredRepositories( final ConfigurationService configurationService, final RepositoryFactory repositoryFactory, final @Named( "system" ) Repository systemRepository ) { this.configurationService = configurationService; this.repositoryFactory = repositoryFactory; this.systemRepository = systemRepository; } @SuppressWarnings( "unchecked" ) @PostConstruct public void loadRepositories() { repositoriesByAlias.clear(); repositoriesByBranchRoot.clear(); final List<ConfigGroup> repoConfigs = configurationService.getConfiguration( REPOSITORY ); if ( !(repoConfigs == null || repoConfigs.isEmpty()) ) { for ( final ConfigGroup configGroup : repoConfigs ) { final Repository repository = repositoryFactory.newRepository( configGroup ); add( repository ); } } } /** * * @param alias Name of the repository. * @return Repository that has a random branch as a root, usually master if master exists. */ public Repository getRepositoryByRepositoryAlias( final String alias ) { return repositoriesByAlias.get( alias ); } /** * This can also return System Repository. * @param fs * @return */ public Repository getRepositoryByRepositoryFileSystem( final FileSystem fs ) { if ( fs == null ) { return null; } if ( convert( systemRepository.getRoot() ).getFileSystem().equals( fs ) ) { return systemRepository; } for ( final Repository repository : repositoriesByAlias.values() ) { if ( convert( repository.getRoot() ).getFileSystem().equals( fs ) ) { return repository; } } return null; } /** * @param root Path to the repository root in any branch. * @return Repository root branch is still the default, usually master. */ public Repository getRepositoryByRootPath( final Path root ) { return repositoriesByBranchRoot.get( root ); } /** * @return Does not include system repository. */ public List<Repository> getAllConfiguredRepositories() { return new ArrayList<>( repositoriesByAlias.values() ); } public boolean containsAlias( final String alias ) { return repositoriesByAlias.containsKey( alias ) || SystemRepository.SYSTEM_REPO.getAlias().equals( alias ); } public void add( final Repository repository ) { repositoriesByAlias.put( repository.getAlias(), repository ); if ( repository instanceof GitRepository && repository.getBranches() != null ) { for ( String branch : repository.getBranches() ) { repositoriesByBranchRoot.put( repository.getBranchRoot( branch ), repository ); } } else { repositoriesByBranchRoot.put( repository.getRoot(), repository ); } } public void update( final Repository updatedRepo ) { add( updatedRepo ); } public Repository remove( final String alias ) { final Repository removed = repositoriesByAlias.remove( alias ); removeFromRootByAlias( alias ); return removed; } private void removeFromRootByAlias( final String alias ) { for ( Path path : findFromRootMapByAlias( alias ) ) { repositoriesByBranchRoot.remove( path ); } } private List<Path> findFromRootMapByAlias( final String alias ) { List<Path> result = new ArrayList<>(); for ( Path path : repositoriesByBranchRoot.keySet() ) { if ( repositoriesByBranchRoot.get( path ).getAlias().equals( alias ) ) { result.add( path ); } } return result; } public void onNewBranch( final @Observes NewBranchEvent changedEvent ) { if ( repositoriesByAlias.containsKey( changedEvent.getRepositoryAlias() ) ) { final Repository repository = getRepositoryByRepositoryAlias( changedEvent.getRepositoryAlias() ); if ( repository instanceof GitRepository ) { (( GitRepository ) repository).addBranch( changedEvent.getBranchName(), changedEvent.getBranchPath() ); repositoriesByBranchRoot.put( changedEvent.getBranchPath(), repository ); } } } public void flush( final @Observes @org.guvnor.structure.backend.config.Repository SystemRepositoryChangedEvent changedEvent ) { loadRepositories(); } }