Package org.sonatype.nexus.proxy.maven.routing.internal

Source Code of org.sonatype.nexus.proxy.maven.routing.internal.EventDispatcher

/*
* Sonatype Nexus (TM) Open Source Version
* Copyright (c) 2007-2014 Sonatype, Inc.
* All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
*
* This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
* which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
*
* Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
* of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
* Eclipse Foundation. All other trademarks are the property of their respective owners.
*/
package org.sonatype.nexus.proxy.maven.routing.internal;

import java.io.IOException;

import org.sonatype.nexus.proxy.RequestContext;
import org.sonatype.nexus.proxy.events.RepositoryConfigurationUpdatedEvent;
import org.sonatype.nexus.proxy.events.RepositoryItemEvent;
import org.sonatype.nexus.proxy.events.RepositoryItemEventCache;
import org.sonatype.nexus.proxy.events.RepositoryItemEventDelete;
import org.sonatype.nexus.proxy.events.RepositoryItemEventDeleteRoot;
import org.sonatype.nexus.proxy.events.RepositoryItemEventStore;
import org.sonatype.nexus.proxy.events.RepositoryRegistryEventAdd;
import org.sonatype.nexus.proxy.item.StorageFileItem;
import org.sonatype.nexus.proxy.item.StorageItem;
import org.sonatype.nexus.proxy.item.uid.IsHiddenAttribute;
import org.sonatype.nexus.proxy.maven.MavenHostedRepository;
import org.sonatype.nexus.proxy.maven.MavenRepository;
import org.sonatype.nexus.proxy.maven.maven2.Maven2ContentClass;
import org.sonatype.nexus.proxy.maven.routing.Manager;
import org.sonatype.nexus.proxy.maven.routing.PrefixSource;
import org.sonatype.nexus.proxy.repository.Repository;
import org.sonatype.nexus.proxy.repository.ShadowRepository;
import org.sonatype.nexus.proxy.utils.RepositoryStringUtils;

import com.google.common.eventbus.AllowConcurrentEvents;
import com.google.common.eventbus.Subscribe;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import static com.google.common.base.Preconditions.checkNotNull;

/**
* Internal class routing various Nexus events to {@link Manager}.
* <p>
* Note: This component was initially marked as {@code @EagerSingleton}, but it did not play well with rest of plexus
* components, as it broke everything. Seems like this component was created "too early", also, some UTs does not
* prepare environment properly (like DefaultPasswordGeneratorTest, that does not set even the minimal properties
* needed). Hence, this component is made a "plain" singleton (not eager), and {@link Manager} implementation will
* pull it up, to have it created and to start ticking.
*
* @author cstamas
* @since 2.4
*/
public class EventDispatcher
{
  private static final Logger logger = LoggerFactory.getLogger(EventDispatcher.class);

  private final Manager manager;

  /**
   * Da constructor.
   */
  public EventDispatcher(final Manager manager) {
    this.manager = checkNotNull(manager);
  }

  protected Logger getLogger() {
    return logger;
  }

  // actual work is done here

  protected void handleRepositoryAdded(final MavenRepository mavenRepository) {
    manager.initializePrefixFile(mavenRepository);
  }

  protected void handleRepositoryModified(final MavenRepository mavenRepository) {
    try {
      manager.forceUpdatePrefixFile(mavenRepository);
    }
    catch (IllegalStateException e) {
      // we will end up here regularly if reconfiguration was about putting repository out of service
      getLogger().debug("Repository {} is in bad state for prefix file update: {}",
          mavenRepository, e.getMessage());
    }
  }

  protected void handlePrefixFileUpdate(final RepositoryItemEvent evt) {
    final MavenRepository mavenRepository = (MavenRepository) evt.getRepository();
    try {
      final PrefixSource prefixSource = manager.getPrefixSourceFor(mavenRepository);
      manager.publish(mavenRepository, prefixSource);
    }
    catch (IOException e) {
      getLogger().warn("Problem while publishing prefix file for repository {}",
          RepositoryStringUtils.getHumanizedNameString(mavenRepository), e);
    }
  }

  protected void handlePrefixFileRemoval(final RepositoryItemEvent evt) {
    final MavenRepository mavenRepository = (MavenRepository) evt.getRepository();
    try {
      manager.unpublish(mavenRepository);
    }
    catch (IOException e) {
      getLogger().warn("Problem while unpublishing prefix file for repository {}",
          RepositoryStringUtils.getHumanizedNameString(mavenRepository), e);
    }
  }

  protected void offerPath(final MavenHostedRepository mavenHostedRepository, StorageItem item) {
    try {
      manager.offerEntry(mavenHostedRepository, item);
    }
    catch (IOException e) {
      getLogger().warn("Problem while maintaining prefix file for hosted repository {}, offered entry={}",
          RepositoryStringUtils.getHumanizedNameString(mavenHostedRepository), item, e);
    }
  }

  protected void revokePath(final MavenHostedRepository mavenHostedRepository, StorageItem item) {
    try {
      manager.revokeEntry(mavenHostedRepository, item);
    }
    catch (IOException e) {
      getLogger().warn("Problem while maintaining prefix file for hosted repository {}, revoked entry={}",
          RepositoryStringUtils.getHumanizedNameString(mavenHostedRepository), item, e);
    }
  }

  // == Filters

  protected boolean isRequestContextMarked(final RequestContext context) {
    return context.containsKey(Manager.ROUTING_INITIATED_FILE_OPERATION_FLAG_KEY);
  }

  protected boolean isRepositoryHandled(final Repository repository) {
    // we handle repository events if repo is not out of service, and only for non-shadow repository
    // that are Maven2 reposes
    return repository != null && repository.getRepositoryKind().isFacetAvailable(MavenRepository.class)
        && !repository.getRepositoryKind().isFacetAvailable(ShadowRepository.class)
        && Maven2ContentClass.ID.equals(repository.getRepositoryContentClass().getId());
  }

  protected boolean isPrefixFileEvent(final RepositoryItemEvent evt) {
    // is not fired as side effect of Publisher publishing this
    return isRepositoryHandled(evt.getRepository()) && !isRequestContextMarked(evt.getItem().getItemContext())
        && manager.isEventAboutPrefixFile(evt);
  }

  protected boolean isPlainItemEvent(final RepositoryItemEvent evt) {
    // is not fired as side effect of Publisher publishing this
    return isRepositoryHandled(evt.getRepository()) && !isRequestContextMarked(evt.getItem().getItemContext())
        && !evt.getItem().getRepositoryItemUid().getBooleanAttributeValue(IsHiddenAttribute.class);
  }

  protected boolean isPlainFileItemEvent(final RepositoryItemEvent evt) {
    // is not fired as side effect of Publisher publishing this
    return isPlainItemEvent(evt) && evt.getItem() instanceof StorageFileItem;
  }

  // == handlers for item events (to maintain prefix list file)

  /**
   * Event handler.
   */
  @Subscribe
  @AllowConcurrentEvents
  public void onRepositoryItemEventStore(final RepositoryItemEventStore evt) {
    if (isPrefixFileEvent(evt)) {
      handlePrefixFileUpdate(evt);
    }
    else if (isPlainFileItemEvent(evt)) {
      // we maintain prefix list for hosted reposes only!
      final MavenHostedRepository mavenHostedRepository =
          evt.getRepository().adaptToFacet(MavenHostedRepository.class);
      if (mavenHostedRepository != null) {
        offerPath(mavenHostedRepository, evt.getItem());
      }
    }
  }

  /**
   * Event handler.
   */
  @Subscribe
  @AllowConcurrentEvents
  public void onRepositoryItemEventCache(final RepositoryItemEventCache evt) {
    if (isPrefixFileEvent(evt)) {
      handlePrefixFileUpdate(evt);
    }
    else if (isPlainFileItemEvent(evt)) {
      // we maintain prefix list for hosted reposes only!
      final MavenHostedRepository mavenHostedRepository =
          evt.getRepository().adaptToFacet(MavenHostedRepository.class);
      if (mavenHostedRepository != null) {
        offerPath(mavenHostedRepository, evt.getItem());
      }
    }
  }

  /**
   * Event handler.
   */
  @Subscribe
  @AllowConcurrentEvents
  public void onRepositoryItemEventDelete(final RepositoryItemEventDelete evt) {
    if (isPrefixFileEvent(evt)) {
      handlePrefixFileRemoval(evt);
    }
    else if (evt instanceof RepositoryItemEventDeleteRoot && isPlainItemEvent(evt)) {
      // we maintain prefix list for hosted reposes only!
      final MavenHostedRepository mavenHostedRepository =
          evt.getRepository().adaptToFacet(MavenHostedRepository.class);
      if (mavenHostedRepository != null) {
        revokePath(mavenHostedRepository, evt.getItem());
      }
    }
  }

  // == Handler for prefix list initialization

  /**
   * Event handler.
   */
  @Subscribe
  @AllowConcurrentEvents
  public void onRepositoryRegistryEventAdd(final RepositoryRegistryEventAdd evt) {
    if (isRepositoryHandled(evt.getRepository())) {
      final MavenRepository mavenRepository = evt.getRepository().adaptToFacet(MavenRepository.class);
      handleRepositoryAdded(mavenRepository);
    }
  }

  // == Handlers for Proxy remote URL changes

  /**
   * Event handler.
   */
  @Subscribe
  @AllowConcurrentEvents
  public void onRepositoryConfigurationUpdatedEvent(final RepositoryConfigurationUpdatedEvent evt) {
    if (isRepositoryHandled(evt.getRepository())) {
      final MavenRepository mavenRepository = evt.getRepository().adaptToFacet(MavenRepository.class);
      handleRepositoryModified(mavenRepository);
    }
  }
}
TOP

Related Classes of org.sonatype.nexus.proxy.maven.routing.internal.EventDispatcher

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.