1 package org.apache.archiva.rest.services;
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
21 import org.apache.archiva.admin.model.beans.ManagedRepository;
22 import org.apache.archiva.common.utils.VersionComparator;
23 import org.apache.archiva.dependency.tree.maven2.DependencyTreeBuilder;
24 import org.apache.archiva.dependency.tree.maven2.Maven3DependencyTreeBuilder;
25 import org.apache.archiva.maven2.model.Artifact;
26 import org.apache.archiva.maven2.model.TreeEntry;
27 import org.apache.archiva.metadata.generic.GenericMetadataFacet;
28 import org.apache.archiva.metadata.model.ArtifactMetadata;
29 import org.apache.archiva.metadata.model.MetadataFacet;
30 import org.apache.archiva.metadata.model.ProjectVersionMetadata;
31 import org.apache.archiva.metadata.model.ProjectVersionReference;
32 import org.apache.archiva.metadata.repository.MetadataRepository;
33 import org.apache.archiva.metadata.repository.MetadataRepositoryException;
34 import org.apache.archiva.metadata.repository.MetadataResolutionException;
35 import org.apache.archiva.metadata.repository.MetadataResolver;
36 import org.apache.archiva.metadata.repository.RepositorySession;
37 import org.apache.archiva.metadata.repository.storage.maven2.ArtifactMetadataVersionComparator;
38 import org.apache.archiva.metadata.repository.storage.maven2.MavenProjectFacet;
39 import org.apache.archiva.model.ArchivaArtifact;
40 import org.apache.archiva.repository.ManagedRepositoryContent;
41 import org.apache.archiva.repository.RepositoryContentFactory;
42 import org.apache.archiva.repository.RepositoryException;
43 import org.apache.archiva.repository.RepositoryNotFoundException;
44 import org.apache.archiva.rest.api.model.ArtifactContent;
45 import org.apache.archiva.rest.api.model.ArtifactContentEntry;
46 import org.apache.archiva.rest.api.model.BrowseResult;
47 import org.apache.archiva.rest.api.model.BrowseResultEntry;
48 import org.apache.archiva.rest.api.model.Entry;
49 import org.apache.archiva.rest.api.model.VersionsList;
50 import org.apache.archiva.rest.api.services.ArchivaRestServiceException;
51 import org.apache.archiva.rest.api.services.BrowseService;
52 import org.apache.archiva.rest.services.utils.ArtifactContentEntryComparator;
53 import org.apache.archiva.rest.services.utils.ArtifactDownloadInfoBuilder;
54 import org.apache.archiva.security.ArchivaSecurityException;
55 import org.apache.commons.collections.CollectionUtils;
56 import org.apache.commons.io.FileUtils;
57 import org.apache.commons.io.IOUtils;
58 import org.apache.commons.lang.StringUtils;
59 import org.springframework.stereotype.Service;
61 import javax.inject.Inject;
62 import javax.ws.rs.core.Response;
64 import java.io.IOException;
65 import java.io.InputStream;
66 import java.util.ArrayList;
67 import java.util.Arrays;
68 import java.util.Collection;
69 import java.util.Collections;
70 import java.util.Enumeration;
71 import java.util.HashMap;
72 import java.util.LinkedHashSet;
73 import java.util.List;
76 import java.util.jar.JarEntry;
77 import java.util.jar.JarFile;
78 import java.util.zip.ZipEntry;
81 * @author Olivier Lamy
84 @Service( "browseService#rest" )
85 public class DefaultBrowseService
86 extends AbstractRestService
87 implements BrowseService
91 private DependencyTreeBuilder dependencyTreeBuilder;
94 private Maven3DependencyTreeBuilder maven3DependencyTreeBuilder;
97 private RepositoryContentFactory repositoryContentFactory;
99 public BrowseResult getRootGroups( String repositoryId )
100 throws ArchivaRestServiceException
102 List<String> selectedRepos = getSelectedRepos( repositoryId );
104 Set<String> namespaces = new LinkedHashSet<String>();
106 // TODO: this logic should be optional, particularly remembering we want to keep this code simple
107 // it is located here to avoid the content repository implementation needing to do too much for what
108 // is essentially presentation code
109 Set<String> namespacesToCollapse;
110 RepositorySession repositorySession = repositorySessionFactory.createSession();
113 MetadataResolver metadataResolver = repositorySession.getResolver();
114 namespacesToCollapse = new LinkedHashSet<String>();
116 for ( String repoId : selectedRepos )
118 namespacesToCollapse.addAll( metadataResolver.resolveRootNamespaces( repositorySession, repoId ) );
120 for ( String n : namespacesToCollapse )
122 // TODO: check performance of this
123 namespaces.add( collapseNamespaces( repositorySession, metadataResolver, selectedRepos, n ) );
126 catch ( MetadataResolutionException e )
128 throw new ArchivaRestServiceException( e.getMessage(),
129 Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), e );
133 repositorySession.close();
136 List<BrowseResultEntry> browseGroupResultEntries = new ArrayList<BrowseResultEntry>( namespaces.size() );
137 for ( String namespace : namespaces )
139 browseGroupResultEntries.add( new BrowseResultEntry( namespace, false ) );
142 Collections.sort( browseGroupResultEntries );
143 return new BrowseResult( browseGroupResultEntries );
146 public BrowseResult browseGroupId( String groupId, String repositoryId )
147 throws ArchivaRestServiceException
149 List<String> selectedRepos = getSelectedRepos( repositoryId );
151 Set<String> projects = new LinkedHashSet<String>();
153 RepositorySession repositorySession = repositorySessionFactory.createSession();
154 Set<String> namespaces;
157 MetadataResolver metadataResolver = repositorySession.getResolver();
159 Set<String> namespacesToCollapse = new LinkedHashSet<String>();
160 for ( String repoId : selectedRepos )
162 namespacesToCollapse.addAll( metadataResolver.resolveNamespaces( repositorySession, repoId, groupId ) );
164 projects.addAll( metadataResolver.resolveProjects( repositorySession, repoId, groupId ) );
167 // TODO: this logic should be optional, particularly remembering we want to keep this code simple
168 // it is located here to avoid the content repository implementation needing to do too much for what
169 // is essentially presentation code
170 namespaces = new LinkedHashSet<String>();
171 for ( String n : namespacesToCollapse )
173 // TODO: check performance of this
175 collapseNamespaces( repositorySession, metadataResolver, selectedRepos, groupId + "." + n ) );
178 catch ( MetadataResolutionException e )
180 throw new ArchivaRestServiceException( e.getMessage(),
181 Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), e );
185 repositorySession.close();
187 List<BrowseResultEntry> browseGroupResultEntries =
188 new ArrayList<BrowseResultEntry>( namespaces.size() + projects.size() );
189 for ( String namespace : namespaces )
191 browseGroupResultEntries.add( new BrowseResultEntry( namespace, false ) );
193 for ( String project : projects )
195 browseGroupResultEntries.add( new BrowseResultEntry( groupId + '.' + project, true ) );
197 Collections.sort( browseGroupResultEntries );
198 return new BrowseResult( browseGroupResultEntries );
202 public VersionsList getVersionsList( String groupId, String artifactId, String repositoryId )
203 throws ArchivaRestServiceException
205 List<String> selectedRepos = getSelectedRepos( repositoryId );
209 Collection<String> versions = getVersions( selectedRepos, groupId, artifactId );
210 return new VersionsList( new ArrayList<String>( versions ) );
212 catch ( MetadataResolutionException e )
214 throw new ArchivaRestServiceException( e.getMessage(),
215 Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), e );
220 private Collection<String> getVersions( List<String> selectedRepos, String groupId, String artifactId )
221 throws MetadataResolutionException
224 RepositorySession repositorySession = repositorySessionFactory.createSession();
227 MetadataResolver metadataResolver = repositorySession.getResolver();
229 Set<String> versions = new LinkedHashSet<String>();
231 for ( String repoId : selectedRepos )
233 Collection<String> projectVersions =
234 metadataResolver.resolveProjectVersions( repositorySession, repoId, groupId, artifactId );
235 versions.addAll( projectVersions );
238 List<String> sortedVersions = new ArrayList<String>( versions );
240 Collections.sort( sortedVersions, VersionComparator.getInstance() );
242 return sortedVersions;
246 repositorySession.close();
250 public ProjectVersionMetadata getProjectMetadata( String groupId, String artifactId, String version,
251 String repositoryId )
252 throws ArchivaRestServiceException
254 List<String> selectedRepos = getSelectedRepos( repositoryId );
256 RepositorySession repositorySession = null;
259 repositorySession = repositorySessionFactory.createSession();
261 MetadataResolver metadataResolver = repositorySession.getResolver();
263 ProjectVersionMetadata versionMetadata = null;
264 for ( String repoId : selectedRepos )
266 if ( versionMetadata == null || versionMetadata.isIncomplete() )
271 metadataResolver.resolveProjectVersion( repositorySession, repoId, groupId, artifactId,
274 catch ( MetadataResolutionException e )
277 "Skipping invalid metadata while compiling shared model for " + groupId + ":" + artifactId
278 + " in repo " + repoId + ": " + e.getMessage() );
283 return versionMetadata;
287 if ( repositorySession != null )
289 repositorySession.close();
295 public ProjectVersionMetadata getProjectVersionMetadata( String groupId, String artifactId, String repositoryId )
296 throws ArchivaRestServiceException
299 List<String> selectedRepos = getSelectedRepos( repositoryId );
301 RepositorySession repositorySession = null;
305 Collection<String> projectVersions = getVersions( selectedRepos, groupId, artifactId );
307 repositorySession = repositorySessionFactory.createSession();
309 MetadataResolver metadataResolver = repositorySession.getResolver();
311 ProjectVersionMetadata sharedModel = new ProjectVersionMetadata();
313 MavenProjectFacet mavenFacet = new MavenProjectFacet();
314 mavenFacet.setGroupId( groupId );
315 mavenFacet.setArtifactId( artifactId );
316 sharedModel.addFacet( mavenFacet );
318 boolean isFirstVersion = true;
320 for ( String version : projectVersions )
322 ProjectVersionMetadata versionMetadata = null;
323 for ( String repoId : selectedRepos )
325 if ( versionMetadata == null || versionMetadata.isIncomplete() )
330 metadataResolver.resolveProjectVersion( repositorySession, repoId, groupId, artifactId,
333 catch ( MetadataResolutionException e )
335 log.error( "Skipping invalid metadata while compiling shared model for " + groupId + ":"
336 + artifactId + " in repo " + repoId + ": " + e.getMessage() );
341 if ( versionMetadata == null )
346 if ( isFirstVersion )
348 sharedModel = versionMetadata;
349 sharedModel.setId( null );
353 MavenProjectFacet versionMetadataMavenFacet =
354 (MavenProjectFacet) versionMetadata.getFacet( MavenProjectFacet.FACET_ID );
355 if ( versionMetadataMavenFacet != null )
357 if ( mavenFacet.getPackaging() != null && !StringUtils.equalsIgnoreCase(
358 mavenFacet.getPackaging(), versionMetadataMavenFacet.getPackaging() ) )
360 mavenFacet.setPackaging( null );
364 if ( StringUtils.isEmpty( sharedModel.getName() ) && !StringUtils.isEmpty(
365 versionMetadata.getName() ) )
367 sharedModel.setName( versionMetadata.getName() );
370 if ( sharedModel.getDescription() != null && !StringUtils.equalsIgnoreCase(
371 sharedModel.getDescription(), versionMetadata.getDescription() ) )
373 sharedModel.setDescription( StringUtils.isNotEmpty( versionMetadata.getDescription() )
374 ? versionMetadata.getDescription()
378 if ( sharedModel.getIssueManagement() != null && versionMetadata.getIssueManagement() != null
379 && !StringUtils.equalsIgnoreCase( sharedModel.getIssueManagement().getUrl(),
380 versionMetadata.getIssueManagement().getUrl() ) )
382 sharedModel.setIssueManagement( versionMetadata.getIssueManagement() );
385 if ( sharedModel.getCiManagement() != null && versionMetadata.getCiManagement() != null
386 && !StringUtils.equalsIgnoreCase( sharedModel.getCiManagement().getUrl(),
387 versionMetadata.getCiManagement().getUrl() ) )
389 sharedModel.setCiManagement( versionMetadata.getCiManagement() );
392 if ( sharedModel.getOrganization() != null && versionMetadata.getOrganization() != null
393 && !StringUtils.equalsIgnoreCase( sharedModel.getOrganization().getName(),
394 versionMetadata.getOrganization().getName() ) )
396 sharedModel.setOrganization( versionMetadata.getOrganization() );
399 if ( sharedModel.getUrl() != null && !StringUtils.equalsIgnoreCase( sharedModel.getUrl(),
400 versionMetadata.getUrl() ) )
402 sharedModel.setUrl( versionMetadata.getUrl() );
406 isFirstVersion = false;
410 catch ( MetadataResolutionException e )
412 throw new ArchivaRestServiceException( e.getMessage(),
413 Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), e );
417 if ( repositorySession != null )
419 repositorySession.close();
424 public List<TreeEntry> getTreeEntries( String groupId, String artifactId, String version, String repositoryId )
425 throws ArchivaRestServiceException
427 List<String> selectedRepos = getSelectedRepos( repositoryId );
432 return maven3DependencyTreeBuilder.buildDependencyTree( selectedRepos, groupId, artifactId, version );
435 catch ( Exception e )
437 log.error( e.getMessage(), e );
440 return Collections.emptyList();
443 public List<ManagedRepository> getUserRepositories()
444 throws ArchivaRestServiceException
448 return userRepositories.getAccessibleRepositories( getPrincipal() );
450 catch ( ArchivaSecurityException e )
452 throw new ArchivaRestServiceException( "repositories.read.observable.error",
453 Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), e );
457 public List<Artifact> getDependees( String groupId, String artifactId, String version, String repositoryId )
458 throws ArchivaRestServiceException
460 List<ProjectVersionReference> references = new ArrayList<ProjectVersionReference>();
461 // TODO: what if we get duplicates across repositories?
462 RepositorySession repositorySession = repositorySessionFactory.createSession();
465 MetadataResolver metadataResolver = repositorySession.getResolver();
466 for ( String repoId : getObservableRepos() )
468 // TODO: what about if we want to see this irrespective of version?
470 metadataResolver.resolveProjectReferences( repositorySession, repoId, groupId, artifactId,
474 catch ( MetadataResolutionException e )
476 throw new ArchivaRestServiceException( e.getMessage(),
477 Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), e );
481 repositorySession.close();
484 List<Artifact> artifacts = new ArrayList<Artifact>( references.size() );
486 for ( ProjectVersionReference projectVersionReference : references )
488 artifacts.add( new Artifact( projectVersionReference.getNamespace(), projectVersionReference.getProjectId(),
489 projectVersionReference.getProjectVersion() ) );
494 public List<Entry> getMetadatas( String groupId, String artifactId, String version, String repositoryId )
495 throws ArchivaRestServiceException
497 ProjectVersionMetadata projectVersionMetadata =
498 getProjectMetadata( groupId, artifactId, version, repositoryId );
499 if ( projectVersionMetadata == null )
501 return Collections.emptyList();
503 MetadataFacet metadataFacet = projectVersionMetadata.getFacet( GenericMetadataFacet.FACET_ID );
505 if ( metadataFacet == null )
507 return Collections.emptyList();
509 Map<String, String> map = metadataFacet.toProperties();
510 List<Entry> entries = new ArrayList<Entry>( map.size() );
512 for ( Map.Entry<String, String> entry : map.entrySet() )
514 entries.add( new Entry( entry.getKey(), entry.getValue() ) );
520 public Boolean addMetadata( String groupId, String artifactId, String version, String key, String value,
521 String repositoryId )
522 throws ArchivaRestServiceException
524 ProjectVersionMetadata projectVersionMetadata =
525 getProjectMetadata( groupId, artifactId, version, repositoryId );
527 if ( projectVersionMetadata == null )
529 return Boolean.FALSE;
532 Map<String, String> properties = new HashMap<String, String>();
534 MetadataFacet metadataFacet = projectVersionMetadata.getFacet( GenericMetadataFacet.FACET_ID );
536 if ( metadataFacet != null && metadataFacet.toProperties() != null )
538 properties.putAll( metadataFacet.toProperties() );
542 metadataFacet = new GenericMetadataFacet();
545 properties.put( key, value );
547 metadataFacet.fromProperties( properties );
549 projectVersionMetadata.addFacet( metadataFacet );
551 RepositorySession repositorySession = repositorySessionFactory.createSession();
555 MetadataRepository metadataRepository = repositorySession.getRepository();
557 metadataRepository.updateProjectVersion( repositoryId, groupId, artifactId, projectVersionMetadata );
559 repositorySession.save();
561 catch ( MetadataRepositoryException e )
563 log.error( e.getMessage(), e );
564 throw new ArchivaRestServiceException( e.getMessage(),
565 Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), e );
569 repositorySession.close();
574 public Boolean deleteMetadata( String groupId, String artifactId, String version, String key, String repositoryId )
575 throws ArchivaRestServiceException
577 ProjectVersionMetadata projectVersionMetadata =
578 getProjectMetadata( groupId, artifactId, version, repositoryId );
580 if ( projectVersionMetadata == null )
582 return Boolean.FALSE;
585 GenericMetadataFacet metadataFacet =
586 (GenericMetadataFacet) projectVersionMetadata.getFacet( GenericMetadataFacet.FACET_ID );
588 if ( metadataFacet != null && metadataFacet.toProperties() != null )
590 Map<String, String> properties = metadataFacet.toProperties();
591 properties.remove( key );
592 metadataFacet.setAdditionalProperties( properties );
599 RepositorySession repositorySession = repositorySessionFactory.createSession();
603 MetadataRepository metadataRepository = repositorySession.getRepository();
605 metadataRepository.updateProjectVersion( repositoryId, groupId, artifactId, projectVersionMetadata );
607 repositorySession.save();
609 catch ( MetadataRepositoryException e )
611 log.error( e.getMessage(), e );
612 throw new ArchivaRestServiceException( e.getMessage(),
613 Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), e );
617 repositorySession.close();
622 public List<ArtifactContentEntry> getArtifactContentEntries( String groupId, String artifactId, String version,
623 String classifier, String type, String path,
624 String repositoryId )
625 throws ArchivaRestServiceException
627 List<String> selectedRepos = getSelectedRepos( repositoryId );
630 for ( String repoId : selectedRepos )
633 ManagedRepositoryContent managedRepositoryContent =
634 repositoryContentFactory.getManagedRepositoryContent( repoId );
635 ArchivaArtifact archivaArtifact = new ArchivaArtifact( groupId, artifactId, version, classifier,
636 StringUtils.isEmpty( type ) ? "jar" : type,
638 File file = managedRepositoryContent.toFile( archivaArtifact );
641 return readFileEntries( file, path, repoId );
645 catch ( IOException e )
647 log.error( e.getMessage(), e );
648 throw new ArchivaRestServiceException( e.getMessage(),
649 Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), e );
651 catch ( RepositoryNotFoundException e )
653 log.error( e.getMessage(), e );
654 throw new ArchivaRestServiceException( e.getMessage(),
655 Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), e );
657 catch ( RepositoryException e )
659 log.error( e.getMessage(), e );
660 throw new ArchivaRestServiceException( e.getMessage(),
661 Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), e );
663 return Collections.emptyList();
666 public List<Artifact> getArtifactDownloadInfos( String groupId, String artifactId, String version,
667 String repositoryId )
668 throws ArchivaRestServiceException
670 List<String> selectedRepos = getSelectedRepos( repositoryId );
672 List<Artifact> artifactDownloadInfos = new ArrayList<Artifact>();
674 RepositorySession session = repositorySessionFactory.createSession();
676 MetadataResolver metadataResolver = session.getResolver();
680 for ( String repoId : selectedRepos )
682 List<ArtifactMetadata> artifacts = new ArrayList<ArtifactMetadata>(
683 metadataResolver.resolveArtifacts( session, repoId, groupId, artifactId, version ) );
684 Collections.sort( artifacts, ArtifactMetadataVersionComparator.INSTANCE );
686 for ( ArtifactMetadata artifact : artifacts )
689 ArtifactDownloadInfoBuilder builder =
690 new ArtifactDownloadInfoBuilder().forArtifactMetadata( artifact ).withManagedRepositoryContent(
691 repositoryContentFactory.getManagedRepositoryContent( repoId ) );
692 Artifact art = builder.build();
694 art.setUrl( getArtifactUrl( art ) );
695 artifactDownloadInfos.add( art );
700 catch ( RepositoryException e )
702 log.error( e.getMessage(), e );
703 throw new ArchivaRestServiceException( e.getMessage(),
704 Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), e );
706 catch ( MetadataResolutionException e )
708 log.error( e.getMessage(), e );
709 throw new ArchivaRestServiceException( e.getMessage(),
710 Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), e );
714 if ( session != null )
720 return artifactDownloadInfos;
723 public ArtifactContent getArtifactContentText( String groupId, String artifactId, String version, String classifier,
724 String type, String path, String repositoryId )
725 throws ArchivaRestServiceException
727 List<String> selectedRepos = getSelectedRepos( repositoryId );
730 for ( String repoId : selectedRepos )
733 ManagedRepositoryContent managedRepositoryContent =
734 repositoryContentFactory.getManagedRepositoryContent( repoId );
735 ArchivaArtifact archivaArtifact = new ArchivaArtifact( groupId, artifactId, version, classifier,
736 StringUtils.isEmpty( type ) ? "jar" : type,
738 File file = managedRepositoryContent.toFile( archivaArtifact );
739 if ( !file.exists() )
741 log.debug( "file: {} not exists for repository: {} try next repository", file, repoId );
744 if ( StringUtils.isNotBlank( path ) )
746 // zip entry of the path -> path must a real file entry of the archive
747 JarFile jarFile = new JarFile( file );
748 ZipEntry zipEntry = jarFile.getEntry( path );
749 InputStream inputStream = jarFile.getInputStream( zipEntry );
752 return new ArtifactContent( IOUtils.toString( inputStream ), repoId );
756 closeQuietly( jarFile );
757 IOUtils.closeQuietly( inputStream );
760 return new ArtifactContent( FileUtils.readFileToString( file ), repoId );
763 catch ( IOException e )
765 log.error( e.getMessage(), e );
766 throw new ArchivaRestServiceException( e.getMessage(),
767 Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), e );
769 catch ( RepositoryNotFoundException e )
771 log.error( e.getMessage(), e );
772 throw new ArchivaRestServiceException( e.getMessage(),
773 Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), e );
775 catch ( RepositoryException e )
777 log.error( e.getMessage(), e );
778 throw new ArchivaRestServiceException( e.getMessage(),
779 Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), e );
781 log.debug( "artifact: {}:{}:{}:{}:{} not found",
782 Arrays.asList( groupId, artifactId, version, classifier, type ).toArray( new String[5] ) );
784 return new ArtifactContent();
787 private void closeQuietly( JarFile jarFile )
789 if ( jarFile != null )
795 catch ( IOException e )
797 log.warn( "ignore error closing jarFile {}", jarFile.getName() );
802 //---------------------------
804 //---------------------------
806 protected List<ArtifactContentEntry> readFileEntries( File file, String filterPath, String repoId )
809 Map<String, ArtifactContentEntry> artifactContentEntryMap = new HashMap<String, ArtifactContentEntry>();
810 int filterDepth = StringUtils.countMatches( filterPath, "/" );
811 /*if ( filterDepth == 0 )
815 JarFile jarFile = new JarFile( file );
818 Enumeration<JarEntry> jarEntryEnumeration = jarFile.entries();
819 while ( jarEntryEnumeration.hasMoreElements() )
821 JarEntry currentEntry = jarEntryEnumeration.nextElement();
822 String cleanedEntryName =
823 StringUtils.endsWith( currentEntry.getName(), "/" ) ? StringUtils.substringBeforeLast(
824 currentEntry.getName(), "/" ) : currentEntry.getName();
825 String entryRootPath = getRootPath( cleanedEntryName );
826 int depth = StringUtils.countMatches( cleanedEntryName, "/" );
827 if ( StringUtils.isEmpty( filterPath ) && !artifactContentEntryMap.containsKey( entryRootPath )
828 && depth == filterDepth )
831 artifactContentEntryMap.put( entryRootPath,
832 new ArtifactContentEntry( entryRootPath, !currentEntry.isDirectory(),
837 if ( StringUtils.startsWith( cleanedEntryName, filterPath ) && ( depth == filterDepth || (
838 !currentEntry.isDirectory() && depth == filterDepth ) ) )
840 artifactContentEntryMap.put( cleanedEntryName, new ArtifactContentEntry( cleanedEntryName,
841 !currentEntry.isDirectory(),
847 if ( StringUtils.isNotEmpty( filterPath ) )
849 Map<String, ArtifactContentEntry> filteredArtifactContentEntryMap =
850 new HashMap<String, ArtifactContentEntry>();
852 for ( Map.Entry<String, ArtifactContentEntry> entry : artifactContentEntryMap.entrySet() )
854 filteredArtifactContentEntryMap.put( entry.getKey(), entry.getValue() );
857 List<ArtifactContentEntry> sorted = getSmallerDepthEntries( filteredArtifactContentEntryMap );
858 if ( sorted == null )
860 return Collections.emptyList();
862 Collections.sort( sorted, ArtifactContentEntryComparator.INSTANCE );
868 if ( jarFile != null )
873 List<ArtifactContentEntry> sorted = new ArrayList<ArtifactContentEntry>( artifactContentEntryMap.values() );
874 Collections.sort( sorted, ArtifactContentEntryComparator.INSTANCE );
878 private List<ArtifactContentEntry> getSmallerDepthEntries( Map<String, ArtifactContentEntry> entries )
880 int smallestDepth = Integer.MAX_VALUE;
881 Map<Integer, List<ArtifactContentEntry>> perDepthList = new HashMap<Integer, List<ArtifactContentEntry>>();
882 for ( Map.Entry<String, ArtifactContentEntry> entry : entries.entrySet() )
885 ArtifactContentEntry current = entry.getValue();
887 if ( current.getDepth() < smallestDepth )
889 smallestDepth = current.getDepth();
892 List<ArtifactContentEntry> currentList = perDepthList.get( current.getDepth() );
894 if ( currentList == null )
896 currentList = new ArrayList<ArtifactContentEntry>();
897 currentList.add( current );
898 perDepthList.put( current.getDepth(), currentList );
902 currentList.add( current );
907 return perDepthList.get( smallestDepth );
912 * @return org/apache -> org , org -> org
914 private String getRootPath( String path )
916 if ( StringUtils.contains( path, '/' ) )
918 return StringUtils.substringBefore( path, "/" );
923 private List<String> getSelectedRepos( String repositoryId )
924 throws ArchivaRestServiceException
927 List<String> selectedRepos = getObservableRepos();
929 if ( CollectionUtils.isEmpty( selectedRepos ) )
932 return Collections.emptyList();
935 if ( StringUtils.isNotEmpty( repositoryId ) )
937 // check user has karma on the repository
938 if ( !selectedRepos.contains( repositoryId ) )
940 throw new ArchivaRestServiceException( "browse.root.groups.repositoy.denied",
941 Response.Status.FORBIDDEN.getStatusCode(), null );
943 selectedRepos = Collections.singletonList( repositoryId );
945 return selectedRepos;
949 private String collapseNamespaces( RepositorySession repositorySession, MetadataResolver metadataResolver,
950 Collection<String> repoIds, String n )
951 throws MetadataResolutionException
953 Set<String> subNamespaces = new LinkedHashSet<String>();
954 for ( String repoId : repoIds )
956 subNamespaces.addAll( metadataResolver.resolveNamespaces( repositorySession, repoId, n ) );
958 if ( subNamespaces.size() != 1 )
960 log.debug( "{} is not collapsible as it has sub-namespaces: {}", n, subNamespaces );
965 for ( String repoId : repoIds )
967 Collection<String> projects = metadataResolver.resolveProjects( repositorySession, repoId, n );
968 if ( projects != null && !projects.isEmpty() )
970 log.debug( "{} is not collapsible as it has projects", n );
974 return collapseNamespaces( repositorySession, metadataResolver, repoIds,
975 n + "." + subNamespaces.iterator().next() );