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