]> source.dussan.org Git - archiva.git/blob
b01efafd7dd771454cc8ce299ec36576f4f3120f
[archiva.git] /
1 package org.apache.archiva.repository.base;
2
3 /*
4  * Licensed to the Apache Software Foundation (ASF) under one
5  * or more contributor license agreements.  See the NOTICE file
6  * distributed with this work for additional information
7  * regarding copyright ownership.  The ASF licenses this file
8  * to you under the Apache License, Version 2.0 (the
9  * "License"); you may not use this file except in compliance
10  * with the License.  You may obtain a copy of the License at
11  *
12  *  http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing,
15  * software distributed under the License is distributed on an
16  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17  * KIND, either express or implied.  See the License for the
18  * specific language governing permissions and limitations
19  * under the License.
20  */
21
22 import com.cronutils.model.CronType;
23 import com.cronutils.model.definition.CronDefinition;
24 import com.cronutils.model.definition.CronDefinitionBuilder;
25 import com.cronutils.parser.CronParser;
26 import org.apache.archiva.event.Event;
27 import org.apache.archiva.event.EventHandler;
28 import org.apache.archiva.event.EventManager;
29 import org.apache.archiva.event.EventType;
30 import org.apache.archiva.indexer.ArchivaIndexingContext;
31 import org.apache.archiva.repository.EditableRepository;
32 import org.apache.archiva.repository.RepositoryCapabilities;
33 import org.apache.archiva.repository.RepositoryState;
34 import org.apache.archiva.repository.RepositoryType;
35 import org.apache.archiva.repository.UnsupportedFeatureException;
36 import org.apache.archiva.repository.event.*;
37 import org.apache.archiva.repository.storage.RepositoryStorage;
38 import org.apache.archiva.repository.storage.StorageAsset;
39 import org.apache.archiva.repository.features.RepositoryFeature;
40 import org.apache.archiva.repository.features.StagingRepositoryFeature;
41 import org.apache.commons.lang3.StringUtils;
42 import org.slf4j.Logger;
43 import org.slf4j.LoggerFactory;
44
45 import java.io.IOException;
46 import java.io.InputStream;
47 import java.io.OutputStream;
48 import java.net.URI;
49 import java.nio.channels.ReadableByteChannel;
50 import java.nio.channels.WritableByteChannel;
51 import java.nio.file.CopyOption;
52 import java.util.Collections;
53 import java.util.HashMap;
54 import java.util.HashSet;
55 import java.util.Locale;
56 import java.util.Map;
57 import java.util.Set;
58 import java.util.concurrent.atomic.AtomicBoolean;
59 import java.util.function.Consumer;
60
61 /**
62  * Implementation of a repository with the necessary fields for a bare repository.
63  * No features are provided. Capabilities and features must be implemented by concrete classes.
64  *
65  */
66 public abstract class AbstractRepository implements EditableRepository, EventHandler<RepositoryEvent>
67 {
68
69
70     Logger log = LoggerFactory.getLogger(AbstractRepository.class);
71
72     private final AtomicBoolean openStatus = new AtomicBoolean(false);
73
74
75     private final RepositoryType type;
76     private final String id;
77     private Map<Locale, String> names = new HashMap<>(  );
78     private Map<Locale, String> descriptions = new HashMap<>(  );
79
80     private Locale primaryLocale = new Locale("en_US");
81     protected URI location;
82     private URI baseUri;
83     private Set<URI> failoverLocations = new HashSet<>(  );
84     private Set<URI> uFailoverLocations = Collections.unmodifiableSet( failoverLocations );
85     private boolean scanned = true;
86     String schedulingDefinition = "0 0 02 * * ?";
87     private String layout = "default";
88     public static final CronDefinition CRON_DEFINITION = CronDefinitionBuilder.instanceDefinitionFor(CronType.QUARTZ);
89     private RepositoryState state;
90
91     private final EventManager eventManager;
92
93     Map<Class<? extends RepositoryFeature<?>>, RepositoryFeature<?>> featureMap = new HashMap<>(  );
94
95     private ArchivaIndexingContext indexingContext;
96     private RepositoryStorage storage;
97
98     public AbstractRepository(RepositoryType type, String id, String name, RepositoryStorage repositoryStorage) {
99         this.id = id;
100         this.names.put( primaryLocale, name);
101         this.type = type;
102         this.storage = repositoryStorage;
103         this.location = repositoryStorage.getLocation();
104         this.openStatus.compareAndSet(false, true);
105         this.eventManager = new EventManager(this);
106     }
107
108     public AbstractRepository(Locale primaryLocale, RepositoryType type, String id, String name, RepositoryStorage repositoryStorage) {
109         setPrimaryLocale( primaryLocale );
110         this.id = id;
111         this.names.put( primaryLocale, name);
112         this.type = type;
113         this.storage = repositoryStorage;
114         this.location = repositoryStorage.getLocation();
115         this.openStatus.compareAndSet(false, true);
116         this.eventManager = new EventManager(this);
117     }
118
119     protected void setPrimaryLocale(Locale locale) {
120         this.primaryLocale = locale;
121     }
122
123     @Override
124     public String getId( )
125     {
126         return id;
127     }
128
129     @Override
130     public String getName( )
131     {
132         return getName( primaryLocale );
133     }
134
135     @Override
136     public String getName( Locale locale )
137     {
138         return names.get(locale);
139     }
140
141     @Override
142     public String getDescription( )
143     {
144         return getDescription( primaryLocale );
145     }
146
147     @Override
148     public String getDescription( Locale locale )
149     {
150         return descriptions.get(primaryLocale);
151     }
152
153     @Override
154     public RepositoryType getType( )
155     {
156         return type;
157     }
158
159     @Override
160     public URI getLocation( )
161     {
162         return location;
163     }
164
165     @Override
166     public StorageAsset getRoot( )
167     {
168         return storage.getRoot( );
169     }
170
171     @Override
172     public Set<URI> getFailoverLocations( )
173     {
174         return uFailoverLocations;
175     }
176
177     @Override
178     public boolean isScanned( )
179     {
180         return scanned;
181     }
182
183     @Override
184     public String getSchedulingDefinition( )
185     {
186         return schedulingDefinition;
187     }
188
189     @Override
190     public abstract boolean hasIndex( );
191
192     @Override
193     public String getLayout( )
194     {
195         return layout;
196     }
197
198     @Override
199     public abstract RepositoryCapabilities getCapabilities( );
200
201     @SuppressWarnings( "unchecked" )
202     @Override
203     public <T extends RepositoryFeature<T>> RepositoryFeature<T> getFeature( Class<T> clazz ) throws UnsupportedFeatureException
204     {
205         if (featureMap.containsKey( clazz )) {
206             return (RepositoryFeature<T>) featureMap.get(clazz);
207         } else
208         {
209             throw new UnsupportedFeatureException( "Feature " + clazz + " not supported" );
210         }
211     }
212
213     @Override
214     public <T extends RepositoryFeature<T>> boolean supportsFeature( Class<T> clazz )
215     {
216         return featureMap.containsKey( clazz );
217     }
218
219     @Override
220     public Locale getPrimaryLocale( )
221     {
222         return primaryLocale;
223     }
224
225     @Override
226     public void setName( Locale locale, String name )
227     {
228         names.put(locale, name);
229     }
230
231     @Override
232     public void setDescription( Locale locale, String description )
233     {
234         descriptions.put(locale, description);
235     }
236
237     @Override
238     public void setLocation( final URI location )
239     {
240         if (location!=null && ( this.location == null || !this.location.equals(location))) {
241             try {
242                 updateLocation(location);
243             } catch (IOException e) {
244                 log.error("Could not update location of repository {} to {}", getId(), location, e);
245             }
246         }
247     }
248
249     @Override
250     public void updateLocation(URI newLocation) throws IOException {
251         storage.updateLocation(newLocation);
252         this.location = newLocation;
253     }
254
255     @Override
256     public void addFailoverLocation( URI location )
257     {
258         this.failoverLocations.add(location);
259     }
260
261     @Override
262     public void removeFailoverLocation( URI location )
263     {
264         this.failoverLocations.remove( location );
265     }
266
267     @Override
268     public void clearFailoverLocations( )
269     {
270         this.failoverLocations.clear();
271     }
272
273     @Override
274     public void setScanned( boolean scanned )
275     {
276         this.scanned = scanned;
277     }
278
279     @Override
280     public void setLayout( String layout )
281     {
282         this.layout = layout;
283     }
284
285     @Override
286     public void setBaseUri(URI baseUri) {
287         this.baseUri = baseUri;
288     }
289
290     @Override
291     public void setSchedulingDefinition(String cronExpression) {
292         this.schedulingDefinition = cronExpression;
293     }
294
295     @SuppressWarnings( "unchecked" )
296     protected <T extends RepositoryFeature<T>> void addFeature(RepositoryFeature<T> feature) {
297        featureMap.put( (Class<? extends RepositoryFeature<?>>) feature.getClass(), feature);
298     }
299
300     @Override
301     public void setIndexingContext(ArchivaIndexingContext context) {
302         this.indexingContext = context;
303     }
304
305     @Override
306     public ArchivaIndexingContext getIndexingContext() {
307         return indexingContext;
308     }
309
310     @Override
311     public void close() {
312         if (this.openStatus.compareAndSet(true, false)) {
313             ArchivaIndexingContext ctx = getIndexingContext();
314             if (ctx != null) {
315                 try {
316                     ctx.close();
317                 } catch (IOException e) {
318                     log.warn("Error during index context close.", e);
319                 }
320                 this.indexingContext = null;
321
322             }
323             if (supportsFeature(StagingRepositoryFeature.class)) {
324                 StagingRepositoryFeature sf = getFeature(StagingRepositoryFeature.class).get();
325                 if (sf.getStagingRepository() != null) {
326                     sf.getStagingRepository().close();
327                 }
328             }
329             setLastState( RepositoryState.CLOSED );
330         }
331
332     }
333
334     @Override
335     public boolean isOpen() {
336         return openStatus.get();
337     }
338
339     @Override
340     public void handle(RepositoryEvent event) {
341         // We just rethrow the events
342         eventManager.fireEvent(event);
343     }
344
345     @Override
346     public <T extends Event> void registerEventHandler( EventType<T> eventType, EventHandler<? super T> eventHandler) {
347         if (!EventType.isInstanceOf(eventType, RepositoryEvent.ANY)) {
348             throw new IllegalArgumentException("Can only register RepositoryEvent Handlers");
349         }
350         eventManager.registerEventHandler(eventType, eventHandler);
351     }
352
353     @Override
354     public <T extends Event> void unregisterEventHandler(EventType<T> type, EventHandler<? super T> eventHandler) {
355         eventManager.unregisterEventHandler(type, eventHandler);
356     }
357
358     @Override
359     public StorageAsset getAsset(String path )
360     {
361         return storage.getAsset(path);
362     }
363
364     @Override
365     public StorageAsset addAsset( String path, boolean container )
366     {
367         return storage.addAsset(path, container);
368     }
369
370     @Override
371     public void removeAsset( StorageAsset asset ) throws IOException
372     {
373         storage.removeAsset(asset);
374     }
375
376     @Override
377     public StorageAsset moveAsset( StorageAsset origin, String destination, CopyOption... copyOptions ) throws IOException
378     {
379         return storage.moveAsset(origin, destination);
380     }
381
382     @Override
383     public void moveAsset( StorageAsset origin, StorageAsset destination, CopyOption... copyOptions ) throws IOException
384     {
385         storage.moveAsset( origin, destination, copyOptions );
386     }
387
388     @Override
389     public StorageAsset copyAsset( StorageAsset origin, String destination, CopyOption... copyOptions ) throws IOException
390     {
391         return storage.copyAsset(origin, destination);
392     }
393
394     @Override
395     public void copyAsset( StorageAsset origin, StorageAsset destination, CopyOption... copyOptions ) throws IOException
396     {
397         storage.copyAsset( origin, destination, copyOptions);
398     }
399
400     @Override
401     public void consumeData(StorageAsset asset, Consumer<InputStream> consumerFunction, boolean readLock ) throws IOException
402     {
403         storage.consumeData(asset, consumerFunction, readLock);
404     }
405
406     @Override
407     public void consumeDataFromChannel( StorageAsset asset, Consumer<ReadableByteChannel> consumerFunction, boolean readLock ) throws IOException
408     {
409         storage.consumeDataFromChannel( asset, consumerFunction, readLock );
410     }
411
412     @Override
413     public void writeData( StorageAsset asset, Consumer<OutputStream> consumerFunction, boolean writeLock ) throws IOException
414     {
415         storage.writeData( asset, consumerFunction, writeLock );
416     }
417
418     @Override
419     public void writeDataToChannel( StorageAsset asset, Consumer<WritableByteChannel> consumerFunction, boolean writeLock ) throws IOException
420     {
421         storage.writeDataToChannel( asset, consumerFunction, writeLock );
422     }
423
424     protected void setStorage( RepositoryStorage storage) {
425         this.storage = storage;
426     }
427
428     protected RepositoryStorage getStorage() {
429         return storage;
430     }
431
432
433     @Override
434     public RepositoryState getLastState( )
435     {
436         return this.state;
437     }
438
439     @Override
440     public void setLastState( RepositoryState state )
441     {
442         this.state = state;
443     }
444 }