Package org.sonatype.nexus.plugins.p2.repository.group

Source Code of org.sonatype.nexus.plugins.p2.repository.group.P2CompositeGroupRepositoryImpl

/*
* 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.plugins.p2.repository.group;

import java.io.File;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;

import javax.enterprise.inject.Typed;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Provider;

import org.sonatype.nexus.SystemStatus;
import org.sonatype.nexus.configuration.Configurator;
import org.sonatype.nexus.configuration.model.CRepository;
import org.sonatype.nexus.configuration.model.CRepositoryExternalConfigurationHolderFactory;
import org.sonatype.nexus.plugins.p2.repository.P2CompositeGroupRepository;
import org.sonatype.nexus.plugins.p2.repository.P2Constants;
import org.sonatype.nexus.plugins.p2.repository.P2ContentClass;
import org.sonatype.nexus.plugins.p2.repository.internal.NexusUtils;
import org.sonatype.nexus.proxy.IllegalOperationException;
import org.sonatype.nexus.proxy.ItemNotFoundException;
import org.sonatype.nexus.proxy.ResourceStoreRequest;
import org.sonatype.nexus.proxy.StorageException;
import org.sonatype.nexus.proxy.access.Action;
import org.sonatype.nexus.proxy.events.NexusStartedEvent;
import org.sonatype.nexus.proxy.events.RepositoryEventLocalStatusChanged;
import org.sonatype.nexus.proxy.events.RepositoryGroupMembersChangedEvent;
import org.sonatype.nexus.proxy.events.RepositoryRegistryEventAdd;
import org.sonatype.nexus.proxy.item.RepositoryItemUid;
import org.sonatype.nexus.proxy.item.RepositoryItemUidLock;
import org.sonatype.nexus.proxy.item.StorageItem;
import org.sonatype.nexus.proxy.registry.ContentClass;
import org.sonatype.nexus.proxy.repository.AbstractGroupRepository;
import org.sonatype.nexus.proxy.repository.DefaultRepositoryKind;
import org.sonatype.nexus.proxy.repository.GroupRepository;
import org.sonatype.nexus.proxy.repository.RepositoryKind;
import org.sonatype.p2.bridge.CompositeRepository;

import com.google.common.base.Throwables;
import com.google.common.eventbus.Subscribe;
import org.apache.commons.io.FileUtils;
import org.codehaus.plexus.util.xml.Xpp3Dom;
import org.eclipse.sisu.Description;

import static com.google.common.base.Preconditions.checkNotNull;
import static org.sonatype.nexus.plugins.p2.repository.P2Constants.COMPOSITE_ARTIFACTS_XML;
import static org.sonatype.nexus.plugins.p2.repository.P2Constants.COMPOSITE_CONTENT_XML;
import static org.sonatype.nexus.plugins.p2.repository.P2Constants.P2_INDEX;
import static org.sonatype.nexus.plugins.p2.repository.internal.NexusUtils.createTemporaryP2Repository;

/**
* P2 group using P2 composite repositories.
*
* @since 2.6
*/
@Named(P2CompositeGroupRepositoryImpl.ROLE_HINT)
@Typed(GroupRepository.class)
@Description("Eclipse P2 Composite")
public class P2CompositeGroupRepositoryImpl
    extends AbstractGroupRepository
    implements P2CompositeGroupRepository
{
  public static final String ROLE_HINT = "p2-composite";

  private final ContentClass contentClass;

  private final P2GroupRepositoryConfigurator p2GroupRepositoryConfigurator;

  private final CompositeRepository compositeRepository;

  private final Provider<SystemStatus> systemStatusProvider;

  private RepositoryKind repositoryKind;

  @Inject
  public P2CompositeGroupRepositoryImpl(final @Named(P2ContentClass.ID) ContentClass contentClass,
                                        final P2GroupRepositoryConfigurator p2GroupRepositoryConfigurator,
                                        final CompositeRepository compositeRepository,
                                        final Provider<SystemStatus> systemStatusProvider)
  {
    this.contentClass = checkNotNull(contentClass);
    this.p2GroupRepositoryConfigurator = checkNotNull(p2GroupRepositoryConfigurator);
    this.compositeRepository = checkNotNull(compositeRepository);
    this.systemStatusProvider = checkNotNull(systemStatusProvider);
  }

  @Override
  protected Configurator getConfigurator() {
    return p2GroupRepositoryConfigurator;
  }

  @Override
  protected CRepositoryExternalConfigurationHolderFactory<?> getExternalConfigurationHolderFactory() {
    return new CRepositoryExternalConfigurationHolderFactory<P2GroupRepositoryConfiguration>()
    {
      @Override
      public P2GroupRepositoryConfiguration createExternalConfigurationHolder(final CRepository config) {
        return new P2GroupRepositoryConfiguration((Xpp3Dom) config.getExternalConfiguration());
      }
    };
  }

  @Override
  public RepositoryKind getRepositoryKind() {
    if (repositoryKind == null) {
      repositoryKind =
          new DefaultRepositoryKind(GroupRepository.class,
              Arrays.asList(new Class<?>[]{P2CompositeGroupRepository.class}));
    }
    return repositoryKind;
  }

  @Override
  public ContentClass getRepositoryContentClass() {
    return contentClass;
  }

  @Override
  protected StorageItem doRetrieveItem(final ResourceStoreRequest request)
      throws IllegalOperationException, ItemNotFoundException, StorageException
  {
    final RepositoryItemUid uid = createUid(P2Constants.METADATA_LOCK_PATH);
    final RepositoryItemUidLock lock = uid.getLock();
    final boolean requestGroupLocalOnly = request.isRequestGroupLocalOnly();
    try {
      lock.lock(Action.read);
      request.setRequestGroupLocalOnly(true);
      return super.doRetrieveItem(request);
    }
    finally {
      request.setRequestGroupLocalOnly(requestGroupLocalOnly);
      lock.unlock();
    }
  }

  @Override
  protected Collection<StorageItem> doListItems(final ResourceStoreRequest request)
      throws ItemNotFoundException, StorageException
  {
    final RepositoryItemUid uid = createUid(P2Constants.METADATA_LOCK_PATH);
    final RepositoryItemUidLock lock = uid.getLock();
    final boolean requestGroupLocalOnly = request.isRequestGroupLocalOnly();
    try {
      lock.lock(Action.read);
      request.setRequestGroupLocalOnly(true);
      return super.doListItems(request);
    }
    finally {
      request.setRequestGroupLocalOnly(requestGroupLocalOnly);
      lock.unlock();
    }
  }

  @Subscribe
  public void onEvent(final RepositoryGroupMembersChangedEvent event) {
    if (this.equals(event.getRepository())) {
      createP2CompositeXmls(event.getNewRepositoryMemberIds(), true);
    }
  }

  @Subscribe
  public void onEvent(final RepositoryRegistryEventAdd event) {
    if (this.equals(event.getRepository())) {
      createP2CompositeXmls(getMemberRepositoryIds(), false);
    }
  }

  @Subscribe
  public void onEvent(final NexusStartedEvent event) {
    createP2CompositeXmls(getMemberRepositoryIds(), false);
  }

  @Subscribe
  public void onEvent(final RepositoryEventLocalStatusChanged event) {
    if (this.equals(event.getRepository()) && event.getNewLocalStatus().shouldServiceRequest()) {
      createP2CompositeXmls(getMemberRepositoryIds(), true);
    }
  }

  private void createP2CompositeXmls(final List<String> memberRepositoryIds,
                                     final boolean forced)
  {
    if (!getLocalStatus().shouldServiceRequest()
        || !systemStatusProvider.get().isNexusStarted()) {
      return;
    }
    if (!forced) {
      try {
        retrieveItem(true, new ResourceStoreRequest(COMPOSITE_ARTIFACTS_XML));
        // xmls are present, so bailout
        return;
      }
      catch (Exception e) {
        // will regenerate
      }
    }

    try {
      File tempP2Repository = null;
      try {
        tempP2Repository = createTemporaryP2Repository();

        final URI[] memberRepositoryUris = toUris(memberRepositoryIds);

        compositeRepository.addArtifactsRepository(tempP2Repository.toURI(), memberRepositoryUris);
        compositeRepository.addMetadataRepository(tempP2Repository.toURI(), memberRepositoryUris);

        final RepositoryItemUid uid = createUid(P2Constants.METADATA_LOCK_PATH);
        final RepositoryItemUidLock lock = uid.getLock();
        try {
          lock.lock(Action.create);

          NexusUtils.storeItemFromFile(
              COMPOSITE_ARTIFACTS_XML,
              new File(tempP2Repository, COMPOSITE_ARTIFACTS_XML),
              this,
              getMimeSupport().guessMimeTypeFromPath(COMPOSITE_ARTIFACTS_XML)
          );
          NexusUtils.storeItemFromFile(
              COMPOSITE_CONTENT_XML,
              new File(tempP2Repository, COMPOSITE_CONTENT_XML),
              this,
              getMimeSupport().guessMimeTypeFromPath(COMPOSITE_CONTENT_XML)
          );
          NexusUtils.storeItem(
              this,
              new ResourceStoreRequest(P2_INDEX),
              getClass().getResourceAsStream("/META-INF/p2Composite.index"),
              getMimeSupport().guessMimeTypeFromPath(P2_INDEX),
              null
          );
        }
        finally {
          lock.unlock();
        }
      }
      finally {
        FileUtils.deleteDirectory(tempP2Repository);
      }
    }
    catch (Exception e) {
      throw Throwables.propagate(e);
    }
  }

  private URI[] toUris(final List<String> memberRepositoryIds) {
    if (memberRepositoryIds == null || memberRepositoryIds.isEmpty()) {
      return new URI[0];
    }
    final URI[] uris = new URI[memberRepositoryIds.size()];
    for (int i = 0; i < memberRepositoryIds.size(); i++) {
      try {
        uris[i] = new URI("../../repositories/" + memberRepositoryIds.get(i));
      }
      catch (URISyntaxException e) {
        throw Throwables.propagate(e);
      }
    }
    return uris;
  }

}
TOP

Related Classes of org.sonatype.nexus.plugins.p2.repository.group.P2CompositeGroupRepositoryImpl

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.