001/*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *   http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing,
013 * software distributed under the License is distributed on an
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 * KIND, either express or implied.  See the License for the
016 * specific language governing permissions and limitations
017 * under the License.
018 */
019package org.eclipse.aether.internal.impl;
020
021import javax.inject.Inject;
022import javax.inject.Named;
023import javax.inject.Singleton;
024
025import java.util.ArrayList;
026import java.util.Collection;
027import java.util.Set;
028
029import org.eclipse.aether.RepositoryEvent;
030import org.eclipse.aether.RepositoryListener;
031import org.eclipse.aether.impl.RepositoryEventDispatcher;
032import org.eclipse.aether.spi.locator.Service;
033import org.eclipse.aether.spi.locator.ServiceLocator;
034import org.slf4j.Logger;
035import org.slf4j.LoggerFactory;
036
037import static java.util.Objects.requireNonNull;
038
039/**
040 */
041@Singleton
042@Named
043public class DefaultRepositoryEventDispatcher implements RepositoryEventDispatcher, Service {
044
045    private static final Logger LOGGER = LoggerFactory.getLogger(DefaultRepositoryEventDispatcher.class);
046
047    private Collection<RepositoryListener> listeners = new ArrayList<>();
048
049    public DefaultRepositoryEventDispatcher() {
050        // enables no-arg constructor
051    }
052
053    @Inject
054    DefaultRepositoryEventDispatcher(Set<RepositoryListener> listeners) {
055        setRepositoryListeners(listeners);
056    }
057
058    public DefaultRepositoryEventDispatcher addRepositoryListener(RepositoryListener listener) {
059        this.listeners.add(requireNonNull(listener, "repository listener cannot be null"));
060        return this;
061    }
062
063    public DefaultRepositoryEventDispatcher setRepositoryListeners(Collection<RepositoryListener> listeners) {
064        if (listeners == null) {
065            this.listeners = new ArrayList<>();
066        } else {
067            this.listeners = listeners;
068        }
069        return this;
070    }
071
072    public void initService(ServiceLocator locator) {
073        setRepositoryListeners(locator.getServices(RepositoryListener.class));
074    }
075
076    public void dispatch(RepositoryEvent event) {
077        requireNonNull(event, "event cannot be null");
078        if (!listeners.isEmpty()) {
079            for (RepositoryListener listener : listeners) {
080                dispatch(event, listener);
081            }
082        }
083
084        RepositoryListener listener = event.getSession().getRepositoryListener();
085
086        if (listener != null) {
087            dispatch(event, listener);
088        }
089    }
090
091    private void dispatch(RepositoryEvent event, RepositoryListener listener) {
092        try {
093            switch (event.getType()) {
094                case ARTIFACT_DEPLOYED:
095                    listener.artifactDeployed(event);
096                    break;
097                case ARTIFACT_DEPLOYING:
098                    listener.artifactDeploying(event);
099                    break;
100                case ARTIFACT_DESCRIPTOR_INVALID:
101                    listener.artifactDescriptorInvalid(event);
102                    break;
103                case ARTIFACT_DESCRIPTOR_MISSING:
104                    listener.artifactDescriptorMissing(event);
105                    break;
106                case ARTIFACT_DOWNLOADED:
107                    listener.artifactDownloaded(event);
108                    break;
109                case ARTIFACT_DOWNLOADING:
110                    listener.artifactDownloading(event);
111                    break;
112                case ARTIFACT_INSTALLED:
113                    listener.artifactInstalled(event);
114                    break;
115                case ARTIFACT_INSTALLING:
116                    listener.artifactInstalling(event);
117                    break;
118                case ARTIFACT_RESOLVED:
119                    listener.artifactResolved(event);
120                    break;
121                case ARTIFACT_RESOLVING:
122                    listener.artifactResolving(event);
123                    break;
124                case METADATA_DEPLOYED:
125                    listener.metadataDeployed(event);
126                    break;
127                case METADATA_DEPLOYING:
128                    listener.metadataDeploying(event);
129                    break;
130                case METADATA_DOWNLOADED:
131                    listener.metadataDownloaded(event);
132                    break;
133                case METADATA_DOWNLOADING:
134                    listener.metadataDownloading(event);
135                    break;
136                case METADATA_INSTALLED:
137                    listener.metadataInstalled(event);
138                    break;
139                case METADATA_INSTALLING:
140                    listener.metadataInstalling(event);
141                    break;
142                case METADATA_INVALID:
143                    listener.metadataInvalid(event);
144                    break;
145                case METADATA_RESOLVED:
146                    listener.metadataResolved(event);
147                    break;
148                case METADATA_RESOLVING:
149                    listener.metadataResolving(event);
150                    break;
151                default:
152                    throw new IllegalStateException("unknown repository event type " + event.getType());
153            }
154        } catch (Exception | LinkageError e) {
155            logError(e, listener);
156        }
157    }
158
159    private void logError(Throwable e, Object listener) {
160        LOGGER.warn(
161                "Failed to dispatch repository event to {}", listener.getClass().getCanonicalName(), e);
162    }
163}