Package org.sonatype.nexus.obr.group

Source Code of org.sonatype.nexus.obr.group.ObrGroupRepository

/*
* 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.obr.group;

import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import javax.inject.Inject;
import javax.inject.Named;

import org.sonatype.nexus.configuration.Configurator;
import org.sonatype.nexus.configuration.model.CRepository;
import org.sonatype.nexus.configuration.model.CRepositoryExternalConfigurationHolderFactory;
import org.sonatype.nexus.obr.ObrContentClass;
import org.sonatype.nexus.obr.metadata.ManagedObrSite;
import org.sonatype.nexus.obr.metadata.ObrMetadataSource;
import org.sonatype.nexus.obr.metadata.ObrResourceReader;
import org.sonatype.nexus.obr.metadata.ObrResourceWriter;
import org.sonatype.nexus.obr.util.ObrUtils;
import org.sonatype.nexus.proxy.IllegalOperationException;
import org.sonatype.nexus.proxy.ItemNotFoundException;
import org.sonatype.nexus.proxy.NoSuchRepositoryException;
import org.sonatype.nexus.proxy.ResourceStoreRequest;
import org.sonatype.nexus.proxy.StorageException;
import org.sonatype.nexus.proxy.item.RepositoryItemUid;
import org.sonatype.nexus.proxy.item.StorageCollectionItem;
import org.sonatype.nexus.proxy.item.StorageFileItem;
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.InvalidGroupingException;
import org.sonatype.nexus.proxy.repository.Repository;
import org.sonatype.nexus.proxy.repository.RepositoryKind;

import org.apache.commons.io.IOUtils;
import org.codehaus.plexus.util.xml.Xpp3Dom;
import org.eclipse.sisu.Description;
import org.osgi.service.obr.Resource;

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

@Named(ObrGroupRepository.ROLE_HINT)
@Description("OBR Group")
public class ObrGroupRepository
    extends AbstractGroupRepository
    implements GroupRepository
{
  public static final String ROLE_HINT = "obr-group";

  private final ContentClass obrContentClass;

  private final ObrGroupRepositoryConfigurator obrGroupRepositoryConfigurator;

  private final ObrMetadataSource obrMetadataSource;

  private final RepositoryKind obrGroupRepositoryKind = new DefaultRepositoryKind(GroupRepository.class, null);

  private long lastModified = Long.MIN_VALUE;

  @Inject
  public ObrGroupRepository(final @Named(ObrContentClass.ID) ContentClass obrContentClass,
                            final ObrGroupRepositoryConfigurator obrGroupRepositoryConfigurator,
                            final @Named("obr-bindex") ObrMetadataSource obrMetadataSource)
  {
    this.obrContentClass = checkNotNull(obrContentClass);
    this.obrGroupRepositoryConfigurator = checkNotNull(obrGroupRepositoryConfigurator);
    this.obrMetadataSource = checkNotNull(obrMetadataSource);
  }

  public ContentClass getRepositoryContentClass() {
    return obrContentClass;
  }

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

  public RepositoryKind getRepositoryKind() {
    return obrGroupRepositoryKind;
  }

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

  @Override
  public Collection<StorageItem> list(final boolean fromTask, final StorageCollectionItem item)
      throws IllegalOperationException, ItemNotFoundException, StorageException
  {
    return ObrUtils.augmentListedItems(item.getRepositoryItemUid(), super.list(fromTask, item));
  }

  @Override
  protected Collection<StorageItem> doListItems(final ResourceStoreRequest request)
      throws ItemNotFoundException, StorageException
  {
    return getLocalStorage().listItems(this, request);
  }

  @Override
  protected StorageItem doRetrieveItem(final ResourceStoreRequest request)
      throws IllegalOperationException, ItemNotFoundException, StorageException
  {
    final String path = request.getRequestPath();

    if (ObrUtils.isObrMetadataRequest(request)) {
      return mergeObrMetadata(request);
    }
    else if (!"/".equals(path) && !path.startsWith("/.")) {
      return retrieveBundleItem(request);
    }

    return getLocalStorage().retrieveItem(this, request);
  }

  /**
   * Searches through the member OBRs to find the repository that contains the given item.
   *
   * @param request the resource request
   * @return the matching bundle item
   */
  private StorageItem retrieveBundleItem(final ResourceStoreRequest request)
      throws IllegalOperationException, ItemNotFoundException, StorageException
  {
    final String path = request.getRequestPath();

    ObrResourceReader reader = null;
    for (final Repository r : getRequestRepositories(request)) {
      try {
        reader = obrMetadataSource.getReader(new ManagedObrSite(ObrUtils.retrieveObrItem(r)));
        for (Resource i = reader.readResource(); i != null; i = reader.readResource()) {
          final URL url = i.getURL();
          if ("file".equals(url.getProtocol()) && path.equals(url.getPath())) {
            return r.retrieveItem(false, request);
          }
        }
      }
      catch (final IOException e) {
        // ignore
      }
      finally {
        IOUtils.closeQuietly(reader);
      }
    }

    throw new ItemNotFoundException(request, this);
  }

  @Override
  public void setMemberRepositoryIds(final List<String> repositories)
      throws NoSuchRepositoryException, InvalidGroupingException
  {
    lastModified = Long.MIN_VALUE;

    super.setMemberRepositoryIds(repositories);
  }

  @Override
  public void removeMemberRepositoryId(final String repositoryId) {
    lastModified = Long.MIN_VALUE;

    super.removeMemberRepositoryId(repositoryId);
  }

  /**
   * Stream all the member OBRs together into a single OBR.
   *
   * @param request the resource request
   * @return the merged OBR metadata
   */
  private StorageItem mergeObrMetadata(final ResourceStoreRequest request)
      throws StorageException
  {
    final RepositoryItemUid obrUid = createUid(request.getRequestPath());
    StorageItem obrItem = ObrUtils.getCachedItem(obrUid);

    long modified = 0;
    final Collection<StorageFileItem> memberObrItems = new ArrayList<StorageFileItem>();
    for (final Repository r : getMemberRepositories()) {
      try {
        final StorageFileItem item = ObrUtils.retrieveObrItem(r);
        modified = Math.max(modified, item.getModified());
        memberObrItems.add(item);

        if (item.isExpired()) {
          lastModified = Long.MIN_VALUE;
        }
      }
      catch (final StorageException e) {
        // ignore this particular OBR and continue
      }
    }

    if (null == obrItem || lastModified < modified) {
      ObrResourceReader reader = null;
      ObrResourceWriter writer = null;

      try {
        writer = obrMetadataSource.getWriter(createUid(request.getRequestPath()));
        for (final StorageFileItem f : memberObrItems) {
          try {
            reader = obrMetadataSource.getReader(new ManagedObrSite(f));
            for (Resource i = reader.readResource(); i != null; i = reader.readResource()) {
              writer.append(i);
            }
          }
          catch (final IOException e) {
            log.warn("Problem merging OBR metadata from " + f.getRepositoryItemUid(), e);
          }
          finally {
            IOUtils.closeQuietly(reader);
          }
        }

        writer.complete(); // the OBR is only updated once the stream is complete and closed
      }
      finally {
        IOUtils.closeQuietly(writer);
      }

      obrItem = ObrUtils.getCachedItem(obrUid);
      if (null == obrItem) {
        // this shouldn't happen as we just saved it, but just in case...
        throw new StorageException("Problem reading OBR metadata from repository " + getId());
      }

      lastModified = modified;
    }

    return obrItem;
  }
}
TOP

Related Classes of org.sonatype.nexus.obr.group.ObrGroupRepository

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.