This project has retired. For details please refer to its Attic page.
Source code
001package org.apache.archiva.repository;
002
003/*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements.  See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership.  The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License.  You may obtain a copy of the License at
011 *
012 *  http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied.  See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021
022import com.cronutils.model.CronType;
023import com.cronutils.model.definition.CronDefinition;
024import com.cronutils.model.definition.CronDefinitionBuilder;
025import com.cronutils.parser.CronParser;
026import org.apache.archiva.common.utils.PathUtil;
027import org.apache.archiva.indexer.ArchivaIndexingContext;
028import org.apache.archiva.repository.features.RepositoryFeature;
029import org.apache.archiva.repository.features.StagingRepositoryFeature;
030import org.apache.commons.lang.StringUtils;
031import org.slf4j.Logger;
032import org.slf4j.LoggerFactory;
033
034import java.io.IOException;
035import java.net.URI;
036import java.nio.file.Path;
037import java.util.ArrayList;
038import java.util.Collections;
039import java.util.HashMap;
040import java.util.HashSet;
041import java.util.List;
042import java.util.Locale;
043import java.util.Map;
044import java.util.Set;
045
046/**
047 * Implementation of a repository with the necessary fields for a bare repository.
048 * No features are provided. Capabilities and features must be implemented by concrete classes.
049 *
050 */
051public abstract class AbstractRepository implements EditableRepository, RepositoryEventListener
052{
053
054
055    Logger log = LoggerFactory.getLogger(AbstractRepository.class);
056
057    private final RepositoryType type;
058    private final String id;
059    private Map<Locale, String> names = new HashMap<>(  );
060    private Map<Locale, String> descriptions = new HashMap<>(  );
061
062    private Locale primaryLocale = new Locale("en_US");
063    private URI location;
064    private URI baseUri;
065    private Set<URI> failoverLocations = new HashSet<>(  );
066    private Set<URI> uFailoverLocations = Collections.unmodifiableSet( failoverLocations );
067    private boolean scanned = true;
068    String schedulingDefinition = "0 0 02 * * ?";
069    private String layout = "default";
070    public static final CronDefinition CRON_DEFINITION = CronDefinitionBuilder.instanceDefinitionFor(CronType.QUARTZ);
071    private List<RepositoryEventListener> listeners = new ArrayList<>();
072
073
074    Map<Class<? extends RepositoryFeature<?>>, RepositoryFeature<?>> featureMap = new HashMap<>(  );
075
076    protected Path repositoryBase;
077    private ArchivaIndexingContext indexingContext;
078
079    public AbstractRepository(RepositoryType type, String id, String name, Path repositoryBase) {
080        this.id = id;
081        this.names.put( primaryLocale, name);
082        this.type = type;
083        this.repositoryBase=repositoryBase;
084    }
085
086    public AbstractRepository(Locale primaryLocale, RepositoryType type, String id, String name, Path repositoryBase) {
087        setPrimaryLocale( primaryLocale );
088        this.id = id;
089        this.names.put( primaryLocale, name);
090        this.type = type;
091        this.repositoryBase=repositoryBase;
092    }
093
094    protected void setPrimaryLocale(Locale locale) {
095        this.primaryLocale = locale;
096    }
097
098    @Override
099    public String getId( )
100    {
101        return id;
102    }
103
104    @Override
105    public String getName( )
106    {
107        return getName( primaryLocale );
108    }
109
110    @Override
111    public String getName( Locale locale )
112    {
113        return names.get(locale);
114    }
115
116    @Override
117    public String getDescription( )
118    {
119        return getDescription( primaryLocale );
120    }
121
122    @Override
123    public String getDescription( Locale locale )
124    {
125        return descriptions.get(primaryLocale);
126    }
127
128    @Override
129    public RepositoryType getType( )
130    {
131        return type;
132    }
133
134    @Override
135    public URI getLocation( )
136    {
137        return location;
138    }
139
140    @Override
141    public Path getLocalPath() {
142        Path localPath;
143        if (StringUtils.isEmpty(getLocation().getScheme()) || "file".equals(getLocation().getScheme()) ) {
144            localPath = PathUtil.getPathFromUri(getLocation());
145            if (localPath.isAbsolute()) {
146                return localPath;
147            } else {
148                return repositoryBase.resolve(localPath);
149            }
150        } else {
151            return repositoryBase.resolve(getId());
152        }
153    }
154
155    @Override
156    public Set<URI> getFailoverLocations( )
157    {
158        return uFailoverLocations;
159    }
160
161    @Override
162    public boolean isScanned( )
163    {
164        return scanned;
165    }
166
167    @Override
168    public String getSchedulingDefinition( )
169    {
170        return schedulingDefinition;
171    }
172
173    @Override
174    public abstract boolean hasIndex( );
175
176    @Override
177    public String getLayout( )
178    {
179        return layout;
180    }
181
182    @Override
183    public abstract RepositoryCapabilities getCapabilities( );
184
185    @SuppressWarnings( "unchecked" )
186    @Override
187    public <T extends RepositoryFeature<T>> RepositoryFeature<T> getFeature( Class<T> clazz ) throws UnsupportedFeatureException
188    {
189        if (featureMap.containsKey( clazz )) {
190            return (RepositoryFeature<T>) featureMap.get(clazz);
191        } else
192        {
193            throw new UnsupportedFeatureException( "Feature " + clazz + " not supported" );
194        }
195    }
196
197    @Override
198    public <T extends RepositoryFeature<T>> boolean supportsFeature( Class<T> clazz )
199    {
200        return featureMap.containsKey( clazz );
201    }
202
203    @Override
204    public Locale getPrimaryLocale( )
205    {
206        return primaryLocale;
207    }
208
209    @Override
210    public void setName( Locale locale, String name )
211    {
212        names.put(locale, name);
213    }
214
215    @Override
216    public void setDescription( Locale locale, String description )
217    {
218        descriptions.put(locale, description);
219    }
220
221    @Override
222    public void setLocation( URI location )
223    {
224        this.location = location;
225    }
226
227    @Override
228    public void addFailoverLocation( URI location )
229    {
230        this.failoverLocations.add(location);
231    }
232
233    @Override
234    public void removeFailoverLocation( URI location )
235    {
236        this.failoverLocations.remove( location );
237    }
238
239    @Override
240    public void clearFailoverLocations( )
241    {
242        this.failoverLocations.clear();
243    }
244
245    @Override
246    public void setScanned( boolean scanned )
247    {
248        this.scanned = scanned;
249    }
250
251    @Override
252    public void setLayout( String layout )
253    {
254        this.layout = layout;
255    }
256
257    @Override
258    public void setBaseUri(URI baseUri) {
259        this.baseUri = baseUri;
260    }
261
262    @Override
263    public void setSchedulingDefinition(String cronExpression) {
264        CronParser parser = new CronParser(CRON_DEFINITION);
265        parser.parse(cronExpression).validate();
266        this.schedulingDefinition = cronExpression;
267    }
268
269    @SuppressWarnings( "unchecked" )
270    protected <T extends RepositoryFeature<T>> void addFeature(RepositoryFeature<T> feature) {
271       featureMap.put( (Class<? extends RepositoryFeature<?>>) feature.getClass(), feature);
272    }
273
274    @Override
275    public void setIndexingContext(ArchivaIndexingContext context) {
276        this.indexingContext = context;
277    }
278
279    @Override
280    public ArchivaIndexingContext getIndexingContext() {
281        return indexingContext;
282    }
283
284    @Override
285    public void close() {
286        ArchivaIndexingContext ctx = getIndexingContext();
287        if (ctx!=null) {
288            try {
289                ctx.close();
290            } catch (IOException e) {
291                log.warn("Error during index context close.",e);
292            }
293        }
294        if (supportsFeature(StagingRepositoryFeature.class)) {
295            StagingRepositoryFeature sf = getFeature(StagingRepositoryFeature.class).get();
296            if (sf.getStagingRepository()!=null) {
297                sf.getStagingRepository().close();
298            }
299        }
300        clearListeners();
301    }
302
303    @Override
304    public <T> void raise(RepositoryEvent<T> event) {
305        for(RepositoryEventListener listener : listeners) {
306            listener.raise(event);
307        }
308    }
309
310    public void addListener(RepositoryEventListener listener) {
311        if (!this.listeners.contains(listener)) {
312            this.listeners.add(listener);
313        }
314    }
315
316    public void removeListener(RepositoryEventListener listener) {
317        this.removeListener(listener);
318    }
319
320    public void clearListeners() {
321        this.listeners.clear();
322    }
323
324}