/* * 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. * * 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.git; import java.net.URI; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import org.guvnor.structure.repositories.PublicURI; import org.guvnor.structure.repositories.Repository; import org.guvnor.structure.repositories.impl.DefaultPublicURI; import org.guvnor.structure.repositories.impl.git.GitRepository; import org.guvnor.structure.server.config.ConfigGroup; import org.guvnor.structure.server.config.ConfigItem; import org.guvnor.structure.server.config.PasswordService; import org.guvnor.structure.server.config.SecureConfigItem; import org.uberfire.backend.vfs.Path; import org.uberfire.io.IOService; import org.uberfire.java.nio.file.FileSystem; import org.uberfire.java.nio.file.FileSystemAlreadyExistsException; import static org.uberfire.backend.server.util.Paths.*; public class GitRepositoryBuilder { private final IOService ioService; private final PasswordService secureService; private GitRepository repo; public GitRepositoryBuilder( final IOService ioService, final PasswordService secureService ) { this.ioService = ioService; this.secureService = secureService; } public Repository build( final ConfigGroup repoConfig ) { repo = new GitRepository( repoConfig.getName() ); if ( !repo.isValid() ) { throw new IllegalStateException( "Repository " + repoConfig.getName() + " not valid" ); } else { addEnvironmentParameters( repoConfig.getItems() ); FileSystem fileSystem = createFileSystem( repo ); setBranches( fileSystem ); setPublicURIs( fileSystem ); return repo; } } private void setPublicURIs( final FileSystem fileSystem ) { final String[] uris = fileSystem.toString().split( "\\r?\\n" ); final List<PublicURI> publicURIs = new ArrayList<PublicURI>( uris.length ); for ( final String s : uris ) { final int protocolStart = s.indexOf( "://" ); publicURIs.add( getPublicURI( s, protocolStart ) ); } repo.setPublicURIs( publicURIs ); } private PublicURI getPublicURI( final String s, final int protocolStart ) { if ( protocolStart > 0 ) { return new DefaultPublicURI( s.substring( 0, protocolStart ), s ); } else { return new DefaultPublicURI( s ); } } private void setBranches( final FileSystem fileSystem ) { final Map<String, Path> branches = getBranches( fileSystem ); repo.setBranches( branches ); repo.setRoot( getDefaultRoot( fileSystem, branches ) ); } private void addEnvironmentParameters( final Collection<ConfigItem> items ) { for ( final ConfigItem item : items ) { if ( item instanceof SecureConfigItem ) { repo.addEnvironmentParameter( item.getName(), secureService.decrypt( item.getValue().toString() ) ); } else { repo.addEnvironmentParameter( item.getName(), item.getValue() ); } } } private org.uberfire.backend.vfs.Path getDefaultRoot( final FileSystem fileSystem, final Map<String, org.uberfire.backend.vfs.Path> branches ) { org.uberfire.backend.vfs.Path defaultRoot; if ( branches.containsKey( "master" ) ) { defaultRoot = branches.get( "master" ); } else { defaultRoot = convert( fileSystem.getRootDirectories().iterator().next() ); } return defaultRoot; } private FileSystem createFileSystem( final GitRepository repo ) { FileSystem fs = null; URI uri = null; try { uri = URI.create( repo.getUri() ); fs = newFileSystem( uri ); } catch ( final FileSystemAlreadyExistsException e ) { fs = ioService.getFileSystem( uri ); Object replaceIfExists = repo.getEnvironment().get( "replaceIfExists" ); if ( replaceIfExists != null && Boolean.valueOf( replaceIfExists.toString() ) ) { org.uberfire.java.nio.file.Path root = fs.getPath( null ); ioService.delete( root ); fs = newFileSystem( uri ); } } catch ( final Throwable ex ) { throw new RuntimeException( ex.getCause().getMessage(), ex ); } return fs; } private FileSystem newFileSystem( URI uri ) { return ioService.newFileSystem( uri, new HashMap<String, Object>( repo.getEnvironment() ) {{ if ( !repo.getEnvironment().containsKey( "origin" ) ) { put( "init", true ); } }} ); } /** * collect all branches * @param fs * @return */ private Map<String, org.uberfire.backend.vfs.Path> getBranches(final FileSystem fs ) { Map<String, org.uberfire.backend.vfs.Path> branches = new HashMap<String, org.uberfire.backend.vfs.Path>(); for ( final org.uberfire.java.nio.file.Path path : fs.getRootDirectories() ) { String gitBranch = getBranchName( path ); branches.put( gitBranch, convert( path ) ); } return branches; } protected String getBranchName( final org.uberfire.java.nio.file.Path path ) { URI uri = path.toUri(); String gitBranch = uri.getAuthority(); if ( gitBranch.indexOf( "@" ) != -1 ) { return gitBranch.split( "@" )[0]; } return gitBranch; } }