You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

MavenRepositoryRequestInfo.java 9.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. package org.apache.archiva.repository.content.maven2;
  2. /*
  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
  10. *
  11. * http://www.apache.org/licenses/LICENSE-2.0
  12. *
  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
  18. * under the License.
  19. */
  20. import org.apache.archiva.model.ArtifactReference;
  21. import org.apache.archiva.repository.*;
  22. import org.apache.archiva.repository.content.PathParser;
  23. import org.apache.archiva.repository.features.RepositoryFeature;
  24. import org.apache.archiva.repository.metadata.MetadataTools;
  25. import org.apache.commons.lang.StringUtils;
  26. /**
  27. * RepositoryRequest is used to determine the type of request that is incoming, and convert it to an appropriate
  28. * ArtifactReference.
  29. */
  30. public class MavenRepositoryRequestInfo implements RepositoryRequestInfo
  31. {
  32. private PathParser defaultPathParser = new DefaultPathParser();
  33. ManagedRepository repository;
  34. public MavenRepositoryRequestInfo(ManagedRepository repository)
  35. {
  36. this.repository = repository;
  37. }
  38. /**
  39. * Takes an incoming requested path (in "/" format) and gleans the layout
  40. * and ArtifactReference appropriate for that content.
  41. *
  42. * @param requestedPath the relative path to the content.
  43. * @return the ArtifactReference for the requestedPath.
  44. * @throws LayoutException if the request path is not layout valid.
  45. */
  46. public ArtifactReference toArtifactReference( String requestedPath )
  47. throws LayoutException
  48. {
  49. if ( StringUtils.isBlank( requestedPath ) )
  50. {
  51. throw new LayoutException( "Blank request path is not a valid." );
  52. }
  53. String path = requestedPath;
  54. while ( path.startsWith( "/" ) )
  55. {
  56. path = path.substring( 1 );
  57. // Only slash? that's bad, mmm-kay?
  58. if ( "/".equals( path ) )
  59. {
  60. throw new LayoutException( "Invalid request path: Slash only." );
  61. }
  62. }
  63. if ( isDefault( path ) )
  64. {
  65. return defaultPathParser.toArtifactReference( path );
  66. }
  67. else if ( isLegacy( path ) )
  68. {
  69. throw new LayoutException( "Legacy Maven1 repository not supported anymore." );
  70. }
  71. else
  72. {
  73. throw new LayoutException( "Not a valid request path layout, too short." );
  74. }
  75. }
  76. /**
  77. * <p>
  78. * Tests the path to see if it conforms to the expectations of a metadata request.
  79. * </p>
  80. * <p>
  81. * NOTE: This does a cursory check on the path's last element. A result of true
  82. * from this method is not a guarantee that the metadata is in a valid format, or
  83. * that it even contains data.
  84. * </p>
  85. *
  86. * @param requestedPath the path to test.
  87. * @return true if the requestedPath is likely a metadata request.
  88. */
  89. public boolean isMetadata( String requestedPath )
  90. {
  91. return requestedPath.endsWith( "/" + MetadataTools.MAVEN_METADATA );
  92. }
  93. /**
  94. * @param requestedPath
  95. * @return true if the requestedPath is likely an archetype catalog request.
  96. */
  97. public boolean isArchetypeCatalog( String requestedPath )
  98. {
  99. return requestedPath.endsWith( "/" + MetadataTools.MAVEN_ARCHETYPE_CATALOG );
  100. }
  101. /**
  102. * <p>
  103. * Tests the path to see if it conforms to the expectations of a support file request.
  104. * </p>
  105. * <p>
  106. * Tests for <code>.sha1</code>, <code>.md5</code>, <code>.asc</code>, and <code>.php</code>.
  107. * </p>
  108. * <p>
  109. * NOTE: This does a cursory check on the path's extension only. A result of true
  110. * from this method is not a guarantee that the support resource is in a valid format, or
  111. * that it even contains data.
  112. * </p>
  113. *
  114. * @param requestedPath the path to test.
  115. * @return true if the requestedPath is likely that of a support file request.
  116. */
  117. public boolean isSupportFile( String requestedPath )
  118. {
  119. int idx = requestedPath.lastIndexOf( '.' );
  120. if ( idx <= 0 )
  121. {
  122. return false;
  123. }
  124. String ext = requestedPath.substring( idx );
  125. return ( ".sha1".equals( ext ) || ".md5".equals( ext ) || ".asc".equals( ext ) || ".pgp".equals( ext ) );
  126. }
  127. public boolean isMetadataSupportFile( String requestedPath )
  128. {
  129. if ( isSupportFile( requestedPath ) )
  130. {
  131. String basefilePath = StringUtils.substring( requestedPath, 0, requestedPath.lastIndexOf( '.' ) );
  132. if ( isMetadata( basefilePath ) )
  133. {
  134. return true;
  135. }
  136. }
  137. return false;
  138. }
  139. @Override
  140. public String getLayout(String requestPath) {
  141. if (isDefault(requestPath)) {
  142. return "default";
  143. } else if (isLegacy(requestPath)) {
  144. return "legacy";
  145. } else {
  146. return "unknown";
  147. }
  148. }
  149. /**
  150. * <p>
  151. * Tests the path to see if it conforms to the expectations of a default layout request.
  152. * </p>
  153. * <p>
  154. * NOTE: This does a cursory check on the count of path elements only. A result of
  155. * true from this method is not a guarantee that the path sections are valid and
  156. * can be resolved to an artifact reference. use {@link #toArtifactReference(String)}
  157. * if you want a more complete analysis of the validity of the path.
  158. * </p>
  159. *
  160. * @param requestedPath the path to test.
  161. * @return true if the requestedPath is likely that of a default layout request.
  162. */
  163. private boolean isDefault( String requestedPath )
  164. {
  165. if ( StringUtils.isBlank( requestedPath ) )
  166. {
  167. return false;
  168. }
  169. String pathParts[] = StringUtils.splitPreserveAllTokens( requestedPath, '/' );
  170. if ( pathParts.length > 3 )
  171. {
  172. return true;
  173. }
  174. else if ( pathParts.length == 3 )
  175. {
  176. // check if artifact-level metadata (ex. eclipse/jdtcore/maven-metadata.xml)
  177. if ( isMetadata( requestedPath ) )
  178. {
  179. return true;
  180. }
  181. else
  182. {
  183. // check if checksum of artifact-level metadata (ex. eclipse/jdtcore/maven-metadata.xml.sha1)
  184. int idx = requestedPath.lastIndexOf( '.' );
  185. if ( idx > 0 )
  186. {
  187. String base = requestedPath.substring( 0, idx );
  188. if ( isMetadata( base ) && isSupportFile( requestedPath ) )
  189. {
  190. return true;
  191. }
  192. }
  193. return false;
  194. }
  195. }
  196. else
  197. {
  198. return false;
  199. }
  200. }
  201. /**
  202. * <p>
  203. * Tests the path to see if it conforms to the expectations of a legacy layout request.
  204. * </p>
  205. * <p>
  206. * NOTE: This does a cursory check on the count of path elements only. A result of
  207. * true from this method is not a guarantee that the path sections are valid and
  208. * can be resolved to an artifact reference. use {@link #toArtifactReference(String)}
  209. * if you want a more complete analysis of the validity of the path.
  210. * </p>
  211. *
  212. * @param requestedPath the path to test.
  213. * @return true if the requestedPath is likely that of a legacy layout request.
  214. */
  215. private boolean isLegacy( String requestedPath )
  216. {
  217. if ( StringUtils.isBlank( requestedPath ) )
  218. {
  219. return false;
  220. }
  221. String pathParts[] = StringUtils.splitPreserveAllTokens( requestedPath, '/' );
  222. return pathParts.length == 3;
  223. }
  224. /**
  225. * Adjust the requestedPath to conform to the native layout of the provided {@link org.apache.archiva.repository.ManagedRepositoryContent}.
  226. *
  227. * @param requestedPath the incoming requested path.
  228. * @return the adjusted (to native) path.
  229. * @throws LayoutException if the path cannot be parsed.
  230. */
  231. public String toNativePath( String requestedPath)
  232. throws LayoutException
  233. {
  234. if ( StringUtils.isBlank( requestedPath ) )
  235. {
  236. throw new LayoutException( "Request Path is blank." );
  237. }
  238. String referencedResource = requestedPath;
  239. // No checksum by default.
  240. String supportfile = "";
  241. // Figure out support file, and actual referencedResource.
  242. if ( isSupportFile( requestedPath ) )
  243. {
  244. int idx = requestedPath.lastIndexOf( '.' );
  245. referencedResource = requestedPath.substring( 0, idx );
  246. supportfile = requestedPath.substring( idx );
  247. }
  248. if ( isMetadata( referencedResource ) )
  249. {
  250. /* Nothing to translate.
  251. * Default layout is the only layout that can contain maven-metadata.xml files, and
  252. * if the managedRepository is layout legacy, this request would never occur.
  253. */
  254. return requestedPath;
  255. }
  256. // Treat as an artifact reference.
  257. ArtifactReference ref = toArtifactReference( referencedResource );
  258. String adjustedPath = repository.getContent().toPath( ref );
  259. return adjustedPath + supportfile;
  260. }
  261. @Override
  262. public <T extends RepositoryFeature<T>> RepositoryFeature<T> getFeature(Class<T> clazz) throws UnsupportedFeatureException {
  263. return null;
  264. }
  265. @Override
  266. public <T extends RepositoryFeature<T>> boolean supportsFeature(Class<T> clazz) {
  267. return false;
  268. }
  269. }