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.RepositoryAdminException;
22 import org.apache.archiva.admin.model.beans.ManagedRepository;
23 import org.apache.archiva.common.utils.VersionComparator;
24 import org.apache.archiva.common.utils.VersionUtil;
25 import org.apache.archiva.dependency.tree.maven2.DependencyTreeBuilder;
26 import org.apache.archiva.maven2.model.Artifact;
27 import org.apache.archiva.maven2.model.TreeEntry;
28 import org.apache.archiva.metadata.generic.GenericMetadataFacet;
29 import org.apache.archiva.metadata.model.ArtifactMetadata;
30 import org.apache.archiva.metadata.model.MetadataFacet;
31 import org.apache.archiva.metadata.model.ProjectVersionMetadata;
32 import org.apache.archiva.metadata.model.ProjectVersionReference;
33 import org.apache.archiva.metadata.repository.MetadataRepository;
34 import org.apache.archiva.metadata.repository.MetadataRepositoryException;
35 import org.apache.archiva.metadata.repository.MetadataResolutionException;
36 import org.apache.archiva.metadata.repository.MetadataResolver;
37 import org.apache.archiva.metadata.repository.RepositorySession;
38 import org.apache.archiva.metadata.repository.storage.maven2.ArtifactMetadataVersionComparator;
39 import org.apache.archiva.metadata.repository.storage.maven2.MavenProjectFacet;
40 import org.apache.archiva.model.ArchivaArtifact;
41 import org.apache.archiva.proxy.model.RepositoryProxyConnectors;
42 import org.apache.archiva.repository.ManagedRepositoryContent;
43 import org.apache.archiva.repository.RepositoryContentFactory;
44 import org.apache.archiva.repository.RepositoryException;
45 import org.apache.archiva.repository.RepositoryNotFoundException;
46 import org.apache.archiva.rest.api.model.ArtifactContent;
47 import org.apache.archiva.rest.api.model.ArtifactContentEntry;
48 import org.apache.archiva.rest.api.model.BrowseResult;
49 import org.apache.archiva.rest.api.model.BrowseResultEntry;
50 import org.apache.archiva.rest.api.model.Entry;
51 import org.apache.archiva.rest.api.model.MetadataAddRequest;
52 import org.apache.archiva.rest.api.model.VersionsList;
53 import org.apache.archiva.rest.api.services.ArchivaRestServiceException;
54 import org.apache.archiva.rest.api.services.BrowseService;
55 import org.apache.archiva.rest.services.utils.ArtifactContentEntryComparator;
56 import org.apache.archiva.security.ArchivaSecurityException;
57 import org.apache.commons.collections.CollectionUtils;
58 import org.apache.commons.io.FileUtils;
59 import org.apache.commons.io.IOUtils;
60 import org.apache.commons.lang.StringUtils;
61 import org.springframework.stereotype.Service;
63 import javax.inject.Inject;
64 import javax.inject.Named;
65 import javax.ws.rs.core.Response;
67 import java.io.IOException;
68 import java.io.InputStream;
69 import java.util.ArrayList;
70 import java.util.Collection;
71 import java.util.Collections;
72 import java.util.Enumeration;
73 import java.util.HashMap;
74 import java.util.LinkedHashSet;
75 import java.util.List;
78 import java.util.jar.JarEntry;
79 import java.util.jar.JarFile;
80 import java.util.zip.ZipEntry;
83 * @author Olivier Lamy
86 @Service( "browseService#rest" )
87 public class DefaultBrowseService
88 extends AbstractRestService
89 implements BrowseService
93 private DependencyTreeBuilder dependencyTreeBuilder;
96 private RepositoryContentFactory repositoryContentFactory;
99 @Named( value = "repositoryProxyConnectors#default" )
100 private RepositoryProxyConnectors connectors;
102 public BrowseResult getRootGroups( String repositoryId )
103 throws ArchivaRestServiceException
105 List<String> selectedRepos = getSelectedRepos( repositoryId );
107 Set<String> namespaces = new LinkedHashSet<String>();
109 // TODO: this logic should be optional, particularly remembering we want to keep this code simple
110 // it is located here to avoid the content repository implementation needing to do too much for what
111 // is essentially presentation code
112 Set<String> namespacesToCollapse;
113 RepositorySession repositorySession = repositorySessionFactory.createSession();
116 MetadataResolver metadataResolver = repositorySession.getResolver();
117 namespacesToCollapse = new LinkedHashSet<String>();
119 for ( String repoId : selectedRepos )
121 namespacesToCollapse.addAll( metadataResolver.resolveRootNamespaces( repositorySession, repoId ) );
123 for ( String n : namespacesToCollapse )
125 // TODO: check performance of this
126 namespaces.add( collapseNamespaces( repositorySession, metadataResolver, selectedRepos, n ) );
129 catch ( MetadataResolutionException e )
131 throw new ArchivaRestServiceException( e.getMessage(),
132 Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), e );
136 repositorySession.close();
139 List<BrowseResultEntry> browseGroupResultEntries = new ArrayList<BrowseResultEntry>( namespaces.size() );
140 for ( String namespace : namespaces )
142 browseGroupResultEntries.add( new BrowseResultEntry( namespace, false ) );
145 Collections.sort( browseGroupResultEntries );
146 return new BrowseResult( browseGroupResultEntries );
149 public BrowseResult browseGroupId( String groupId, String repositoryId )
150 throws ArchivaRestServiceException
152 List<String> selectedRepos = getSelectedRepos( repositoryId );
154 Set<String> projects = new LinkedHashSet<String>();
156 RepositorySession repositorySession = repositorySessionFactory.createSession();
157 Set<String> namespaces;
160 MetadataResolver metadataResolver = repositorySession.getResolver();
162 Set<String> namespacesToCollapse = new LinkedHashSet<String>();
163 for ( String repoId : selectedRepos )
165 namespacesToCollapse.addAll( metadataResolver.resolveNamespaces( repositorySession, repoId, groupId ) );
167 projects.addAll( metadataResolver.resolveProjects( repositorySession, repoId, groupId ) );
170 // TODO: this logic should be optional, particularly remembering we want to keep this code simple
171 // it is located here to avoid the content repository implementation needing to do too much for what
172 // is essentially presentation code
173 namespaces = new LinkedHashSet<String>();
174 for ( String n : namespacesToCollapse )
176 // TODO: check performance of this
178 collapseNamespaces( repositorySession, metadataResolver, selectedRepos, groupId + "." + n ) );
181 catch ( MetadataResolutionException e )
183 throw new ArchivaRestServiceException( e.getMessage(),
184 Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), e );
188 repositorySession.close();
190 List<BrowseResultEntry> browseGroupResultEntries =
191 new ArrayList<BrowseResultEntry>( namespaces.size() + projects.size() );
192 for ( String namespace : namespaces )
194 browseGroupResultEntries.add( new BrowseResultEntry( namespace, false ) );
196 for ( String project : projects )
198 browseGroupResultEntries.add( new BrowseResultEntry( groupId + '.' + project, true ) );
200 Collections.sort( browseGroupResultEntries );
201 return new BrowseResult( browseGroupResultEntries );
205 public VersionsList getVersionsList( String groupId, String artifactId, String repositoryId )
206 throws ArchivaRestServiceException
208 List<String> selectedRepos = getSelectedRepos( repositoryId );
212 Collection<String> versions = getVersions( selectedRepos, groupId, artifactId );
213 return new VersionsList( new ArrayList<String>( versions ) );
215 catch ( MetadataResolutionException e )
217 throw new ArchivaRestServiceException( e.getMessage(),
218 Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), e );
223 private Collection<String> getVersions( List<String> selectedRepos, String groupId, String artifactId )
224 throws MetadataResolutionException
227 RepositorySession repositorySession = repositorySessionFactory.createSession();
230 MetadataResolver metadataResolver = repositorySession.getResolver();
232 Set<String> versions = new LinkedHashSet<String>();
234 for ( String repoId : selectedRepos )
236 Collection<String> projectVersions =
237 metadataResolver.resolveProjectVersions( repositorySession, repoId, groupId, artifactId );
238 versions.addAll( projectVersions );
241 List<String> sortedVersions = new ArrayList<String>( versions );
243 Collections.sort( sortedVersions, VersionComparator.getInstance() );
245 return sortedVersions;
249 repositorySession.close();
253 public ProjectVersionMetadata getProjectMetadata( String groupId, String artifactId, String version,
254 String repositoryId )
255 throws ArchivaRestServiceException
257 List<String> selectedRepos = getSelectedRepos( repositoryId );
259 RepositorySession repositorySession = null;
262 repositorySession = repositorySessionFactory.createSession();
264 MetadataResolver metadataResolver = repositorySession.getResolver();
266 ProjectVersionMetadata versionMetadata = null;
267 for ( String repoId : selectedRepos )
269 if ( versionMetadata == null || versionMetadata.isIncomplete() )
274 metadataResolver.resolveProjectVersion( repositorySession, repoId, groupId, artifactId,
277 catch ( MetadataResolutionException e )
280 "Skipping invalid metadata while compiling shared model for " + groupId + ":" + artifactId
281 + " in repo " + repoId + ": " + e.getMessage() );
286 return versionMetadata;
290 if ( repositorySession != null )
292 repositorySession.close();
298 public ProjectVersionMetadata getProjectVersionMetadata( String groupId, String artifactId, String repositoryId )
299 throws ArchivaRestServiceException
302 List<String> selectedRepos = getSelectedRepos( repositoryId );
304 RepositorySession repositorySession = null;
308 Collection<String> projectVersions = getVersions( selectedRepos, groupId, artifactId );
310 repositorySession = repositorySessionFactory.createSession();
312 MetadataResolver metadataResolver = repositorySession.getResolver();
314 ProjectVersionMetadata sharedModel = new ProjectVersionMetadata();
316 MavenProjectFacet mavenFacet = new MavenProjectFacet();
317 mavenFacet.setGroupId( groupId );
318 mavenFacet.setArtifactId( artifactId );
319 sharedModel.addFacet( mavenFacet );
321 boolean isFirstVersion = true;
323 for ( String version : projectVersions )
325 ProjectVersionMetadata versionMetadata = null;
326 for ( String repoId : selectedRepos )
328 if ( versionMetadata == null || versionMetadata.isIncomplete() )
333 metadataResolver.resolveProjectVersion( repositorySession, repoId, groupId, artifactId,
336 catch ( MetadataResolutionException e )
338 log.error( "Skipping invalid metadata while compiling shared model for " + groupId + ":"
339 + artifactId + " in repo " + repoId + ": " + e.getMessage() );
344 if ( versionMetadata == null )
349 if ( isFirstVersion )
351 sharedModel = versionMetadata;
352 sharedModel.setId( null );
356 MavenProjectFacet versionMetadataMavenFacet =
357 (MavenProjectFacet) versionMetadata.getFacet( MavenProjectFacet.FACET_ID );
358 if ( versionMetadataMavenFacet != null )
360 if ( mavenFacet.getPackaging() != null && !StringUtils.equalsIgnoreCase(
361 mavenFacet.getPackaging(), versionMetadataMavenFacet.getPackaging() ) )
363 mavenFacet.setPackaging( null );
367 if ( StringUtils.isEmpty( sharedModel.getName() ) && !StringUtils.isEmpty(
368 versionMetadata.getName() ) )
370 sharedModel.setName( versionMetadata.getName() );
373 if ( sharedModel.getDescription() != null && !StringUtils.equalsIgnoreCase(
374 sharedModel.getDescription(), versionMetadata.getDescription() ) )
376 sharedModel.setDescription( StringUtils.isNotEmpty( versionMetadata.getDescription() )
377 ? versionMetadata.getDescription()
381 if ( sharedModel.getIssueManagement() != null && versionMetadata.getIssueManagement() != null
382 && !StringUtils.equalsIgnoreCase( sharedModel.getIssueManagement().getUrl(),
383 versionMetadata.getIssueManagement().getUrl() ) )
385 sharedModel.setIssueManagement( versionMetadata.getIssueManagement() );
388 if ( sharedModel.getCiManagement() != null && versionMetadata.getCiManagement() != null
389 && !StringUtils.equalsIgnoreCase( sharedModel.getCiManagement().getUrl(),
390 versionMetadata.getCiManagement().getUrl() ) )
392 sharedModel.setCiManagement( versionMetadata.getCiManagement() );
395 if ( sharedModel.getOrganization() != null && versionMetadata.getOrganization() != null
396 && !StringUtils.equalsIgnoreCase( sharedModel.getOrganization().getName(),
397 versionMetadata.getOrganization().getName() ) )
399 sharedModel.setOrganization( versionMetadata.getOrganization() );
402 if ( sharedModel.getUrl() != null && !StringUtils.equalsIgnoreCase( sharedModel.getUrl(),
403 versionMetadata.getUrl() ) )
405 sharedModel.setUrl( versionMetadata.getUrl() );
409 isFirstVersion = false;
413 catch ( MetadataResolutionException e )
415 throw new ArchivaRestServiceException( e.getMessage(),
416 Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), e );
420 if ( repositorySession != null )
422 repositorySession.close();
427 public List<TreeEntry> getTreeEntries( String groupId, String artifactId, String version, String repositoryId )
428 throws ArchivaRestServiceException
430 List<String> selectedRepos = getSelectedRepos( repositoryId );
435 return dependencyTreeBuilder.buildDependencyTree( selectedRepos, groupId, artifactId, version );
438 catch ( Exception e )
440 log.error( e.getMessage(), e );
443 return Collections.emptyList();
446 public List<ManagedRepository> getUserRepositories()
447 throws ArchivaRestServiceException
451 return userRepositories.getAccessibleRepositories( getPrincipal() );
453 catch ( ArchivaSecurityException e )
455 throw new ArchivaRestServiceException( "repositories.read.observable.error",
456 Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), e );
460 public List<Artifact> getDependees( String groupId, String artifactId, String version, String repositoryId )
461 throws ArchivaRestServiceException
463 List<ProjectVersionReference> references = new ArrayList<ProjectVersionReference>();
464 // TODO: what if we get duplicates across repositories?
465 RepositorySession repositorySession = repositorySessionFactory.createSession();
468 MetadataResolver metadataResolver = repositorySession.getResolver();
469 for ( String repoId : getObservableRepos() )
471 // TODO: what about if we want to see this irrespective of version?
473 metadataResolver.resolveProjectReferences( repositorySession, repoId, groupId, artifactId,
477 catch ( MetadataResolutionException e )
479 throw new ArchivaRestServiceException( e.getMessage(),
480 Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), e );
484 repositorySession.close();
487 List<Artifact> artifacts = new ArrayList<Artifact>( references.size() );
489 for ( ProjectVersionReference projectVersionReference : references )
491 artifacts.add( new Artifact( projectVersionReference.getNamespace(), projectVersionReference.getProjectId(),
492 projectVersionReference.getProjectVersion() ) );
497 public List<Entry> getMetadatas( String groupId, String artifactId, String version, String repositoryId )
498 throws ArchivaRestServiceException
500 ProjectVersionMetadata projectVersionMetadata =
501 getProjectMetadata( groupId, artifactId, version, repositoryId );
502 if ( projectVersionMetadata == null )
504 return Collections.emptyList();
506 MetadataFacet metadataFacet = projectVersionMetadata.getFacet( GenericMetadataFacet.FACET_ID );
508 if ( metadataFacet == null )
510 return Collections.emptyList();
512 Map<String, String> map = metadataFacet.toProperties();
513 List<Entry> entries = new ArrayList<Entry>( map.size() );
515 for ( Map.Entry<String, String> entry : map.entrySet() )
517 entries.add( new Entry( entry.getKey(), entry.getValue() ) );
523 public Boolean addMetadata( String groupId, String artifactId, String version, String key, String value,
524 String repositoryId )
525 throws ArchivaRestServiceException
527 ProjectVersionMetadata projectVersionMetadata =
528 getProjectMetadata( groupId, artifactId, version, repositoryId );
530 if ( projectVersionMetadata == null )
532 return Boolean.FALSE;
535 Map<String, String> properties = new HashMap<String, String>();
537 MetadataFacet metadataFacet = projectVersionMetadata.getFacet( GenericMetadataFacet.FACET_ID );
539 if ( metadataFacet != null && metadataFacet.toProperties() != null )
541 properties.putAll( metadataFacet.toProperties() );
545 metadataFacet = new GenericMetadataFacet();
548 properties.put( key, value );
550 metadataFacet.fromProperties( properties );
552 projectVersionMetadata.addFacet( metadataFacet );
554 RepositorySession repositorySession = repositorySessionFactory.createSession();
558 MetadataRepository metadataRepository = repositorySession.getRepository();
560 metadataRepository.updateProjectVersion( repositoryId, groupId, artifactId, projectVersionMetadata );
562 repositorySession.save();
564 catch ( MetadataRepositoryException e )
566 log.error( e.getMessage(), e );
567 throw new ArchivaRestServiceException( e.getMessage(),
568 Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), e );
572 repositorySession.close();
577 public Boolean deleteMetadata( String groupId, String artifactId, String version, String key, String repositoryId )
578 throws ArchivaRestServiceException
580 ProjectVersionMetadata projectVersionMetadata =
581 getProjectMetadata( groupId, artifactId, version, repositoryId );
583 if ( projectVersionMetadata == null )
585 return Boolean.FALSE;
588 GenericMetadataFacet metadataFacet =
589 (GenericMetadataFacet) projectVersionMetadata.getFacet( GenericMetadataFacet.FACET_ID );
591 if ( metadataFacet != null && metadataFacet.toProperties() != null )
593 Map<String, String> properties = metadataFacet.toProperties();
594 properties.remove( key );
595 metadataFacet.setAdditionalProperties( properties );
602 RepositorySession repositorySession = repositorySessionFactory.createSession();
606 MetadataRepository metadataRepository = repositorySession.getRepository();
608 metadataRepository.updateProjectVersion( repositoryId, groupId, artifactId, projectVersionMetadata );
610 repositorySession.save();
612 catch ( MetadataRepositoryException e )
614 log.error( e.getMessage(), e );
615 throw new ArchivaRestServiceException( e.getMessage(),
616 Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), e );
620 repositorySession.close();
625 public List<ArtifactContentEntry> getArtifactContentEntries( String groupId, String artifactId, String version,
626 String classifier, String type, String path,
627 String repositoryId )
628 throws ArchivaRestServiceException
630 List<String> selectedRepos = getSelectedRepos( repositoryId );
633 for ( String repoId : selectedRepos )
636 ManagedRepositoryContent managedRepositoryContent =
637 repositoryContentFactory.getManagedRepositoryContent( repoId );
638 ArchivaArtifact archivaArtifact = new ArchivaArtifact( groupId, artifactId, version, classifier,
639 StringUtils.isEmpty( type ) ? "jar" : type,
641 File file = managedRepositoryContent.toFile( archivaArtifact );
644 return readFileEntries( file, path, repoId );
648 catch ( IOException e )
650 log.error( e.getMessage(), e );
651 throw new ArchivaRestServiceException( e.getMessage(),
652 Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), e );
654 catch ( RepositoryNotFoundException e )
656 log.error( e.getMessage(), e );
657 throw new ArchivaRestServiceException( e.getMessage(),
658 Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), e );
660 catch ( RepositoryException e )
662 log.error( e.getMessage(), e );
663 throw new ArchivaRestServiceException( e.getMessage(),
664 Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), e );
666 return Collections.emptyList();
669 public List<Artifact> getArtifactDownloadInfos( String groupId, String artifactId, String version,
670 String repositoryId )
671 throws ArchivaRestServiceException
673 List<String> selectedRepos = getSelectedRepos( repositoryId );
675 List<Artifact> artifactDownloadInfos = new ArrayList<Artifact>();
677 RepositorySession session = repositorySessionFactory.createSession();
679 MetadataResolver metadataResolver = session.getResolver();
683 for ( String repoId : selectedRepos )
685 List<ArtifactMetadata> artifacts = new ArrayList<ArtifactMetadata>(
686 metadataResolver.resolveArtifacts( session, repoId, groupId, artifactId, version ) );
687 Collections.sort( artifacts, ArtifactMetadataVersionComparator.INSTANCE );
688 if ( artifacts != null && !artifacts.isEmpty() )
690 return buildArtifacts( artifacts, repoId );
694 catch ( MetadataResolutionException e )
696 log.error( e.getMessage(), e );
697 throw new ArchivaRestServiceException( e.getMessage(),
698 Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), e );
702 if ( session != null )
704 session.closeQuietly();
708 return artifactDownloadInfos;
711 public ArtifactContent getArtifactContentText( String groupId, String artifactId, String version, String classifier,
712 String type, String path, String repositoryId )
713 throws ArchivaRestServiceException
715 List<String> selectedRepos = getSelectedRepos( repositoryId );
718 for ( String repoId : selectedRepos )
721 ManagedRepositoryContent managedRepositoryContent =
722 repositoryContentFactory.getManagedRepositoryContent( repoId );
723 ArchivaArtifact archivaArtifact = new ArchivaArtifact( groupId, artifactId, version, classifier,
724 StringUtils.isEmpty( type ) ? "jar" : type,
726 File file = managedRepositoryContent.toFile( archivaArtifact );
727 if ( !file.exists() )
729 log.debug( "file: {} not exists for repository: {} try next repository", file, repoId );
732 if ( StringUtils.isNotBlank( path ) )
734 // zip entry of the path -> path must a real file entry of the archive
735 JarFile jarFile = new JarFile( file );
736 ZipEntry zipEntry = jarFile.getEntry( path );
737 InputStream inputStream = jarFile.getInputStream( zipEntry );
740 return new ArtifactContent( IOUtils.toString( inputStream ), repoId );
744 closeQuietly( jarFile );
745 IOUtils.closeQuietly( inputStream );
748 return new ArtifactContent( FileUtils.readFileToString( file ), repoId );
751 catch ( IOException e )
753 log.error( e.getMessage(), e );
754 throw new ArchivaRestServiceException( e.getMessage(),
755 Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), e );
757 catch ( RepositoryNotFoundException e )
759 log.error( e.getMessage(), e );
760 throw new ArchivaRestServiceException( e.getMessage(),
761 Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), e );
763 catch ( RepositoryException e )
765 log.error( e.getMessage(), e );
766 throw new ArchivaRestServiceException( e.getMessage(),
767 Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), e );
769 log.debug( "artifact: {}:{}:{}:{}:{} not found", groupId, artifactId, version, classifier, type );
771 return new ArtifactContent();
774 public Boolean artifactAvailable( String groupId, String artifactId, String version, String classifier,
775 String repositoryId )
776 throws ArchivaRestServiceException
778 List<String> selectedRepos = getSelectedRepos( repositoryId );
780 boolean snapshot = VersionUtil.isSnapshot( version );
784 for ( String repoId : selectedRepos )
787 ManagedRepository managedRepository = managedRepositoryAdmin.getManagedRepository( repoId );
789 if ( ( snapshot && !managedRepository.isSnapshots() ) || ( !snapshot
790 && managedRepository.isSnapshots() ) )
794 ManagedRepositoryContent managedRepositoryContent =
795 repositoryContentFactory.getManagedRepositoryContent( repoId );
796 // FIXME default to jar which can be wrong for war zip etc....
797 ArchivaArtifact archivaArtifact = new ArchivaArtifact( groupId, artifactId, version,
798 StringUtils.isEmpty( classifier )
800 : classifier, "jar", repoId );
801 File file = managedRepositoryContent.toFile( archivaArtifact );
803 if ( file != null && file.exists() )
808 String path = managedRepositoryContent.toPath( archivaArtifact );
810 file = connectors.fetchFromProxies( managedRepositoryContent, path );
812 if ( file != null && file.exists() )
815 String pomPath = StringUtils.substringBeforeLast( path, ".jar" ) + ".pom";
816 connectors.fetchFromProxies( managedRepositoryContent, pomPath );
821 catch ( RepositoryAdminException e )
823 log.error( e.getMessage(), e );
824 throw new ArchivaRestServiceException( e.getMessage(),
825 Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), e );
827 catch ( RepositoryException e )
829 log.error( e.getMessage(), e );
830 throw new ArchivaRestServiceException( e.getMessage(),
831 Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), e );
837 public Boolean artifactAvailable( String groupId, String artifactId, String version, String repositoryId )
838 throws ArchivaRestServiceException
840 return artifactAvailable( groupId, artifactId, version, null, repositoryId );
843 public List<Artifact> getArtifacts( String repositoryId )
844 throws ArchivaRestServiceException
846 RepositorySession repositorySession = repositorySessionFactory.createSession();
849 List<ArtifactMetadata> artifactMetadatas = repositorySession.getRepository().getArtifacts( repositoryId );
850 return buildArtifacts( artifactMetadatas, repositoryId );
852 catch ( MetadataRepositoryException e )
854 throw new ArchivaRestServiceException( e.getMessage(), e );
858 repositorySession.close();
862 public Boolean importMetadata( MetadataAddRequest metadataAddRequest, String repositoryId )
863 throws ArchivaRestServiceException
865 boolean result = true;
866 for ( Map.Entry<String, String> metadata : metadataAddRequest.getMetadatas().entrySet() )
868 result = addMetadata( metadataAddRequest.getGroupId(), metadataAddRequest.getArtifactId(),
869 metadataAddRequest.getVersion(), metadata.getKey(), metadata.getValue(),
879 //---------------------------
881 //---------------------------
883 private void closeQuietly( JarFile jarFile )
885 if ( jarFile != null )
891 catch ( IOException e )
893 log.warn( "ignore error closing jarFile {}", jarFile.getName() );
898 protected List<ArtifactContentEntry> readFileEntries( File file, String filterPath, String repoId )
901 Map<String, ArtifactContentEntry> artifactContentEntryMap = new HashMap<String, ArtifactContentEntry>();
902 int filterDepth = StringUtils.countMatches( filterPath, "/" );
903 /*if ( filterDepth == 0 )
907 JarFile jarFile = new JarFile( file );
910 Enumeration<JarEntry> jarEntryEnumeration = jarFile.entries();
911 while ( jarEntryEnumeration.hasMoreElements() )
913 JarEntry currentEntry = jarEntryEnumeration.nextElement();
914 String cleanedEntryName =
915 StringUtils.endsWith( currentEntry.getName(), "/" ) ? StringUtils.substringBeforeLast(
916 currentEntry.getName(), "/" ) : currentEntry.getName();
917 String entryRootPath = getRootPath( cleanedEntryName );
918 int depth = StringUtils.countMatches( cleanedEntryName, "/" );
919 if ( StringUtils.isEmpty( filterPath ) && !artifactContentEntryMap.containsKey( entryRootPath )
920 && depth == filterDepth )
923 artifactContentEntryMap.put( entryRootPath,
924 new ArtifactContentEntry( entryRootPath, !currentEntry.isDirectory(),
929 if ( StringUtils.startsWith( cleanedEntryName, filterPath ) && ( depth == filterDepth || (
930 !currentEntry.isDirectory() && depth == filterDepth ) ) )
932 artifactContentEntryMap.put( cleanedEntryName, new ArtifactContentEntry( cleanedEntryName,
933 !currentEntry.isDirectory(),
939 if ( StringUtils.isNotEmpty( filterPath ) )
941 Map<String, ArtifactContentEntry> filteredArtifactContentEntryMap =
942 new HashMap<String, ArtifactContentEntry>();
944 for ( Map.Entry<String, ArtifactContentEntry> entry : artifactContentEntryMap.entrySet() )
946 filteredArtifactContentEntryMap.put( entry.getKey(), entry.getValue() );
949 List<ArtifactContentEntry> sorted = getSmallerDepthEntries( filteredArtifactContentEntryMap );
950 if ( sorted == null )
952 return Collections.emptyList();
954 Collections.sort( sorted, ArtifactContentEntryComparator.INSTANCE );
960 if ( jarFile != null )
965 List<ArtifactContentEntry> sorted = new ArrayList<ArtifactContentEntry>( artifactContentEntryMap.values() );
966 Collections.sort( sorted, ArtifactContentEntryComparator.INSTANCE );
970 private List<ArtifactContentEntry> getSmallerDepthEntries( Map<String, ArtifactContentEntry> entries )
972 int smallestDepth = Integer.MAX_VALUE;
973 Map<Integer, List<ArtifactContentEntry>> perDepthList = new HashMap<Integer, List<ArtifactContentEntry>>();
974 for ( Map.Entry<String, ArtifactContentEntry> entry : entries.entrySet() )
977 ArtifactContentEntry current = entry.getValue();
979 if ( current.getDepth() < smallestDepth )
981 smallestDepth = current.getDepth();
984 List<ArtifactContentEntry> currentList = perDepthList.get( current.getDepth() );
986 if ( currentList == null )
988 currentList = new ArrayList<ArtifactContentEntry>();
989 currentList.add( current );
990 perDepthList.put( current.getDepth(), currentList );
994 currentList.add( current );
999 return perDepthList.get( smallestDepth );
1004 * @return org/apache -> org , org -> org
1006 private String getRootPath( String path )
1008 if ( StringUtils.contains( path, '/' ) )
1010 return StringUtils.substringBefore( path, "/" );
1015 private List<String> getSelectedRepos( String repositoryId )
1016 throws ArchivaRestServiceException
1019 List<String> selectedRepos = getObservableRepos();
1021 if ( CollectionUtils.isEmpty( selectedRepos ) )
1023 return Collections.emptyList();
1026 if ( StringUtils.isNotEmpty( repositoryId ) )
1028 // check user has karma on the repository
1029 if ( !selectedRepos.contains( repositoryId ) )
1031 throw new ArchivaRestServiceException( "browse.root.groups.repositoy.denied",
1032 Response.Status.FORBIDDEN.getStatusCode(), null );
1034 selectedRepos = Collections.singletonList( repositoryId );
1036 return selectedRepos;
1040 private String collapseNamespaces( RepositorySession repositorySession, MetadataResolver metadataResolver,
1041 Collection<String> repoIds, String n )
1042 throws MetadataResolutionException
1044 Set<String> subNamespaces = new LinkedHashSet<String>();
1045 for ( String repoId : repoIds )
1047 subNamespaces.addAll( metadataResolver.resolveNamespaces( repositorySession, repoId, n ) );
1049 if ( subNamespaces.size() != 1 )
1051 log.debug( "{} is not collapsible as it has sub-namespaces: {}", n, subNamespaces );
1056 for ( String repoId : repoIds )
1058 Collection<String> projects = metadataResolver.resolveProjects( repositorySession, repoId, n );
1059 if ( projects != null && !projects.isEmpty() )
1061 log.debug( "{} is not collapsible as it has projects", n );
1065 return collapseNamespaces( repositorySession, metadataResolver, repoIds,
1066 n + "." + subNamespaces.iterator().next() );