/*
* 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();
}
}