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.

AbstractRepository.java 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408
  1. package org.apache.archiva.repository;
  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 com.cronutils.model.CronType;
  21. import com.cronutils.model.definition.CronDefinition;
  22. import com.cronutils.model.definition.CronDefinitionBuilder;
  23. import com.cronutils.parser.CronParser;
  24. import org.apache.archiva.indexer.ArchivaIndexingContext;
  25. import org.apache.archiva.repository.storage.RepositoryStorage;
  26. import org.apache.archiva.repository.storage.StorageAsset;
  27. import org.apache.archiva.repository.features.RepositoryFeature;
  28. import org.apache.archiva.repository.features.StagingRepositoryFeature;
  29. import org.apache.commons.lang.StringUtils;
  30. import org.slf4j.Logger;
  31. import org.slf4j.LoggerFactory;
  32. import java.io.IOException;
  33. import java.io.InputStream;
  34. import java.io.OutputStream;
  35. import java.net.URI;
  36. import java.nio.channels.ReadableByteChannel;
  37. import java.nio.channels.WritableByteChannel;
  38. import java.nio.file.CopyOption;
  39. import java.nio.file.Path;
  40. import java.util.ArrayList;
  41. import java.util.Collections;
  42. import java.util.HashMap;
  43. import java.util.HashSet;
  44. import java.util.List;
  45. import java.util.Locale;
  46. import java.util.Map;
  47. import java.util.Set;
  48. import java.util.function.Consumer;
  49. /**
  50. * Implementation of a repository with the necessary fields for a bare repository.
  51. * No features are provided. Capabilities and features must be implemented by concrete classes.
  52. *
  53. */
  54. public abstract class AbstractRepository implements EditableRepository, RepositoryEventListener
  55. {
  56. Logger log = LoggerFactory.getLogger(AbstractRepository.class);
  57. private final RepositoryType type;
  58. private final String id;
  59. private Map<Locale, String> names = new HashMap<>( );
  60. private Map<Locale, String> descriptions = new HashMap<>( );
  61. private Locale primaryLocale = new Locale("en_US");
  62. private URI location;
  63. private URI baseUri;
  64. private Set<URI> failoverLocations = new HashSet<>( );
  65. private Set<URI> uFailoverLocations = Collections.unmodifiableSet( failoverLocations );
  66. private boolean scanned = true;
  67. String schedulingDefinition = "0 0 02 * * ?";
  68. private String layout = "default";
  69. public static final CronDefinition CRON_DEFINITION = CronDefinitionBuilder.instanceDefinitionFor(CronType.QUARTZ);
  70. private List<RepositoryEventListener> listeners = new ArrayList<>();
  71. Map<Class<? extends RepositoryFeature<?>>, RepositoryFeature<?>> featureMap = new HashMap<>( );
  72. private ArchivaIndexingContext indexingContext;
  73. private RepositoryStorage storage;
  74. public AbstractRepository(RepositoryType type, String id, String name, RepositoryStorage repositoryStorage) {
  75. this.id = id;
  76. this.names.put( primaryLocale, name);
  77. this.type = type;
  78. this.storage = repositoryStorage;
  79. }
  80. public AbstractRepository(Locale primaryLocale, RepositoryType type, String id, String name, RepositoryStorage repositoryStorage) {
  81. setPrimaryLocale( primaryLocale );
  82. this.id = id;
  83. this.names.put( primaryLocale, name);
  84. this.type = type;
  85. this.storage = repositoryStorage;
  86. }
  87. protected void setPrimaryLocale(Locale locale) {
  88. this.primaryLocale = locale;
  89. }
  90. @Override
  91. public String getId( )
  92. {
  93. return id;
  94. }
  95. @Override
  96. public String getName( )
  97. {
  98. return getName( primaryLocale );
  99. }
  100. @Override
  101. public String getName( Locale locale )
  102. {
  103. return names.get(locale);
  104. }
  105. @Override
  106. public String getDescription( )
  107. {
  108. return getDescription( primaryLocale );
  109. }
  110. @Override
  111. public String getDescription( Locale locale )
  112. {
  113. return descriptions.get(primaryLocale);
  114. }
  115. @Override
  116. public RepositoryType getType( )
  117. {
  118. return type;
  119. }
  120. @Override
  121. public URI getLocation( )
  122. {
  123. return location;
  124. }
  125. @Override
  126. public Path getLocalPath() {
  127. return storage.getAsset("").getFilePath();
  128. // Path localPath;
  129. // if (StringUtils.isEmpty(getLocation().getScheme()) || "file".equals(getLocation().getScheme()) ) {
  130. // localPath = PathUtil.getPathFromUri(getLocation());
  131. // if (localPath.isAbsolute()) {
  132. // return localPath;
  133. // } else {
  134. // return repositoryBase.resolve(localPath);
  135. // }
  136. // } else {
  137. // return repositoryBase.resolve(getId());
  138. // }
  139. }
  140. @Override
  141. public Set<URI> getFailoverLocations( )
  142. {
  143. return uFailoverLocations;
  144. }
  145. @Override
  146. public boolean isScanned( )
  147. {
  148. return scanned;
  149. }
  150. @Override
  151. public String getSchedulingDefinition( )
  152. {
  153. return schedulingDefinition;
  154. }
  155. @Override
  156. public abstract boolean hasIndex( );
  157. @Override
  158. public String getLayout( )
  159. {
  160. return layout;
  161. }
  162. @Override
  163. public abstract RepositoryCapabilities getCapabilities( );
  164. @SuppressWarnings( "unchecked" )
  165. @Override
  166. public <T extends RepositoryFeature<T>> RepositoryFeature<T> getFeature( Class<T> clazz ) throws UnsupportedFeatureException
  167. {
  168. if (featureMap.containsKey( clazz )) {
  169. return (RepositoryFeature<T>) featureMap.get(clazz);
  170. } else
  171. {
  172. throw new UnsupportedFeatureException( "Feature " + clazz + " not supported" );
  173. }
  174. }
  175. @Override
  176. public <T extends RepositoryFeature<T>> boolean supportsFeature( Class<T> clazz )
  177. {
  178. return featureMap.containsKey( clazz );
  179. }
  180. @Override
  181. public Locale getPrimaryLocale( )
  182. {
  183. return primaryLocale;
  184. }
  185. @Override
  186. public void setName( Locale locale, String name )
  187. {
  188. names.put(locale, name);
  189. }
  190. @Override
  191. public void setDescription( Locale locale, String description )
  192. {
  193. descriptions.put(locale, description);
  194. }
  195. @Override
  196. public void setLocation( URI location )
  197. {
  198. this.location = location;
  199. }
  200. @Override
  201. public void addFailoverLocation( URI location )
  202. {
  203. this.failoverLocations.add(location);
  204. }
  205. @Override
  206. public void removeFailoverLocation( URI location )
  207. {
  208. this.failoverLocations.remove( location );
  209. }
  210. @Override
  211. public void clearFailoverLocations( )
  212. {
  213. this.failoverLocations.clear();
  214. }
  215. @Override
  216. public void setScanned( boolean scanned )
  217. {
  218. this.scanned = scanned;
  219. }
  220. @Override
  221. public void setLayout( String layout )
  222. {
  223. this.layout = layout;
  224. }
  225. @Override
  226. public void setBaseUri(URI baseUri) {
  227. this.baseUri = baseUri;
  228. }
  229. @Override
  230. public void setSchedulingDefinition(String cronExpression) {
  231. if (StringUtils.isNotEmpty( cronExpression ))
  232. {
  233. CronParser parser = new CronParser( CRON_DEFINITION );
  234. parser.parse( cronExpression ).validate( );
  235. }
  236. this.schedulingDefinition = cronExpression;
  237. }
  238. @SuppressWarnings( "unchecked" )
  239. protected <T extends RepositoryFeature<T>> void addFeature(RepositoryFeature<T> feature) {
  240. featureMap.put( (Class<? extends RepositoryFeature<?>>) feature.getClass(), feature);
  241. }
  242. @Override
  243. public void setIndexingContext(ArchivaIndexingContext context) {
  244. this.indexingContext = context;
  245. }
  246. @Override
  247. public ArchivaIndexingContext getIndexingContext() {
  248. return indexingContext;
  249. }
  250. @Override
  251. public void close() {
  252. ArchivaIndexingContext ctx = getIndexingContext();
  253. if (ctx!=null) {
  254. try {
  255. ctx.close();
  256. } catch (IOException e) {
  257. log.warn("Error during index context close.",e);
  258. }
  259. }
  260. if (supportsFeature(StagingRepositoryFeature.class)) {
  261. StagingRepositoryFeature sf = getFeature(StagingRepositoryFeature.class).get();
  262. if (sf.getStagingRepository()!=null) {
  263. sf.getStagingRepository().close();
  264. }
  265. }
  266. clearListeners();
  267. }
  268. @Override
  269. public <T> void raise(RepositoryEvent<T> event) {
  270. for(RepositoryEventListener listener : listeners) {
  271. listener.raise(event);
  272. }
  273. }
  274. public void addListener(RepositoryEventListener listener) {
  275. if (!this.listeners.contains(listener)) {
  276. this.listeners.add(listener);
  277. }
  278. }
  279. public void removeListener(RepositoryEventListener listener) {
  280. this.removeListener(listener);
  281. }
  282. public void clearListeners() {
  283. this.listeners.clear();
  284. }
  285. @Override
  286. public StorageAsset getAsset(String path )
  287. {
  288. return storage.getAsset(path);
  289. }
  290. @Override
  291. public StorageAsset addAsset( String path, boolean container )
  292. {
  293. return storage.addAsset(path, container);
  294. }
  295. @Override
  296. public void removeAsset( StorageAsset asset ) throws IOException
  297. {
  298. storage.removeAsset(asset);
  299. }
  300. @Override
  301. public StorageAsset moveAsset( StorageAsset origin, String destination, CopyOption... copyOptions ) throws IOException
  302. {
  303. return storage.moveAsset(origin, destination);
  304. }
  305. @Override
  306. public void moveAsset( StorageAsset origin, StorageAsset destination, CopyOption... copyOptions ) throws IOException
  307. {
  308. storage.moveAsset( origin, destination, copyOptions );
  309. }
  310. @Override
  311. public StorageAsset copyAsset( StorageAsset origin, String destination, CopyOption... copyOptions ) throws IOException
  312. {
  313. return storage.copyAsset(origin, destination);
  314. }
  315. @Override
  316. public void copyAsset( StorageAsset origin, StorageAsset destination, CopyOption... copyOptions ) throws IOException
  317. {
  318. storage.copyAsset( origin, destination, copyOptions);
  319. }
  320. @Override
  321. public void consumeData(StorageAsset asset, Consumer<InputStream> consumerFunction, boolean readLock ) throws IOException
  322. {
  323. storage.consumeData(asset, consumerFunction, readLock);
  324. }
  325. @Override
  326. public void consumeDataFromChannel( StorageAsset asset, Consumer<ReadableByteChannel> consumerFunction, boolean readLock ) throws IOException
  327. {
  328. storage.consumeDataFromChannel( asset, consumerFunction, readLock );
  329. }
  330. @Override
  331. public void writeData( StorageAsset asset, Consumer<OutputStream> consumerFunction, boolean writeLock ) throws IOException
  332. {
  333. storage.writeData( asset, consumerFunction, writeLock );
  334. }
  335. @Override
  336. public void writeDataToChannel( StorageAsset asset, Consumer<WritableByteChannel> consumerFunction, boolean writeLock ) throws IOException
  337. {
  338. storage.writeDataToChannel( asset, consumerFunction, writeLock );
  339. }
  340. protected void setStorage( RepositoryStorage storage) {
  341. this.storage = storage;
  342. }
  343. protected RepositoryStorage getStorage() {
  344. return storage;
  345. }
  346. }