/* * 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.git; import java.util.List; import java.util.Optional; import java.util.stream.Collectors; import javax.annotation.PostConstruct; import javax.inject.Inject; import org.guvnor.structure.repositories.GitMetadata; import org.guvnor.structure.repositories.GitMetadataStore; import org.guvnor.structure.repositories.impl.GitMetadataImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.uberfire.backend.server.io.object.ObjectStorage; public class GitMetadataStoreImpl implements GitMetadataStore { private Logger logger = LoggerFactory.getLogger( GitMetadataStoreImpl.class ); public static final String SEPARATOR = "/"; public static final String METADATA = "default://system/metadata"; private ObjectStorage storage; @Inject public GitMetadataStoreImpl( ObjectStorage storage ) { this.storage = storage; } @PostConstruct public void init() { if ( logger.isDebugEnabled() ) { logger.debug( "Initializing GitMetadataStoreImpl {}", METADATA ); } this.storage.init( METADATA ); } @Override public void write( String name ) { this.write( name, "" ); } @Override public void write( String name, String origin ) { GitMetadataImpl repositoryMetadata = (GitMetadataImpl) this.read( name ).orElse( new GitMetadataImpl( name ) ); this.removeForkFromOrigin( repositoryMetadata ); GitMetadataImpl newRepositoryMetadata = new GitMetadataImpl( name, repositoryMetadata.getForks() ); if ( isStorableOrigin( origin ) ) { newRepositoryMetadata = new GitMetadataImpl( name, origin, repositoryMetadata.getForks() ); GitMetadataImpl originMetadata = (GitMetadataImpl) this.read( origin ).orElse( new GitMetadataImpl( origin ) ); List<String> forks = originMetadata.getForks(); forks.add( name ); this.write( origin, new GitMetadataImpl( origin, originMetadata.getOrigin(), forks ) ); } this.write( name, newRepositoryMetadata ); } @Override public void write( String name, GitMetadata metadata ) { this.storage.write( buildPath( name ), metadata ); } @Override public Optional<GitMetadata> read( String name ) { try { final GitMetadataImpl metadata = this.storage.read( buildPath( name ) ); return Optional.ofNullable( metadata ); } catch ( RuntimeException e ) { return Optional.empty(); } } @Override public void delete( String name ) { String path = buildPath( name ); Optional<GitMetadata> optionalMetadata = this.read( name ); optionalMetadata.ifPresent( metadata -> { this.removeForkFromOrigin( metadata ); this.removeOriginFromForks( metadata ); this.storage.delete( path ); } ); } private void removeOriginFromForks( final GitMetadata metadata ) { List<GitMetadata> forks = this.getForks( metadata ); forks.forEach( fork -> { GitMetadata newForkImpl = new GitMetadataImpl( fork.getName(), fork.getForks() ); this.storage.write( buildPath( fork.getName() ), newForkImpl ); } ); } private void removeForkFromOrigin( final GitMetadata metadata ) { this.getOrigin( metadata ).ifPresent( origin -> { if ( origin.getForks().contains( metadata.getName() ) ) { List<String> forks = origin.getForks(); forks.remove( metadata.getName() ); GitMetadataImpl newOrigin = new GitMetadataImpl( origin.getName(), origin.getOrigin(), forks ); this.storage.write( buildPath( origin.getName() ), newOrigin ); } } ); } private Optional<GitMetadata> getOrigin( final GitMetadata metadata ) { return this.read( metadata.getOrigin() ); } private List<GitMetadata> getForks( final GitMetadata metadata ) { return metadata.getForks().stream().map( path -> this.read( path ).get() ).collect( Collectors.toList() ); } private boolean isStorableOrigin( final String origin ) { return origin != null && origin.matches( "(^\\w+\\/\\w+$)" ); } private String buildPath( String name ) { String path = SEPARATOR + name; if ( name.indexOf( SEPARATOR ) == 0 ) { path = name; } if ( path.lastIndexOf( SEPARATOR ) == path.length() - 1 ) { path = path.substring( 0, path.length() ); } return path + ".metadata"; } }