| /******************************************************************************* |
| * Copyright (c) 2007, 2011 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.equinox.internal.p2.ui.model; |
| |
| import java.net.URI; |
| import org.eclipse.core.runtime.*; |
| import org.eclipse.equinox.internal.p2.metadata.repository.MetadataRepositoryManager; |
| import org.eclipse.equinox.internal.p2.ui.*; |
| import org.eclipse.equinox.internal.p2.ui.query.IUViewQueryContext; |
| import org.eclipse.equinox.p2.core.ProvisionException; |
| import org.eclipse.equinox.p2.metadata.IInstallableUnit; |
| import org.eclipse.equinox.p2.query.IQueryable; |
| import org.eclipse.equinox.p2.repository.IRepository; |
| import org.eclipse.equinox.p2.repository.metadata.IMetadataRepository; |
| import org.eclipse.equinox.p2.repository.metadata.IMetadataRepositoryManager; |
| import org.eclipse.equinox.p2.ui.Policy; |
| import org.eclipse.equinox.p2.ui.ProvisioningUI; |
| |
| /** |
| * Element wrapper class for a metadata repository that gets its |
| * contents in a deferred manner. A metadata repository can be the root |
| * (input) of a viewer, when the view is filtered by repo, or a child of |
| * an input, when the view is showing many repos. |
| * |
| * @since 3.4 |
| */ |
| public class MetadataRepositoryElement extends RootElement implements IRepositoryElement<IInstallableUnit> { |
| |
| URI location; |
| boolean isEnabled; |
| String name; |
| |
| public MetadataRepositoryElement(Object parent, URI location, boolean isEnabled) { |
| this(parent, null, null, location, isEnabled); |
| } |
| |
| public MetadataRepositoryElement(IUViewQueryContext queryContext, ProvisioningUI ui, URI location, boolean isEnabled) { |
| this(null, queryContext, ui, location, isEnabled); |
| } |
| |
| public MetadataRepositoryElement(Object parent, IUViewQueryContext queryContext, ProvisioningUI ui, URI location, boolean isEnabled) { |
| super(parent, queryContext, ui); |
| this.location = location; |
| this.isEnabled = isEnabled; |
| } |
| |
| // don't suppress this warning as it will cause build-time warning |
| // see bug 423628. This should be possible to fix once |
| // the entire hierarchy adopts generics |
| public Object getAdapter(Class adapter) { |
| if (adapter == IMetadataRepository.class) |
| return getQueryable(); |
| if (adapter == IRepository.class) |
| return getQueryable(); |
| return super.getAdapter(adapter); |
| } |
| |
| protected Object[] fetchChildren(Object o, IProgressMonitor monitor) { |
| SubMonitor sub = SubMonitor.convert(monitor, 200); |
| // Ensure the repository is loaded using the monitor, so we respond to cancelation. |
| // Otherwise, a non-loaded repository could be loaded in the query provider without a monitor. |
| // If the load fails, return an explanation element. |
| try { |
| getMetadataRepository(sub.newChild(100)); |
| //only invoke super if we successfully loaded the repository |
| return super.fetchChildren(o, sub.newChild(100)); |
| } catch (ProvisionException e) { |
| getProvisioningUI().getRepositoryTracker().reportLoadFailure(location, e); |
| // TODO see https://bugs.eclipse.org/bugs/show_bug.cgi?id=276784 |
| return new Object[] {new EmptyElementExplanation(this, IStatus.ERROR, e.getLocalizedMessage(), "")}; //$NON-NLS-1$ |
| } |
| } |
| |
| protected String getImageId(Object obj) { |
| return ProvUIImages.IMG_METADATA_REPOSITORY; |
| } |
| |
| protected int getDefaultQueryType() { |
| return QueryProvider.AVAILABLE_IUS; |
| } |
| |
| public String getLabel(Object o) { |
| String n = getName(); |
| if (n != null && n.length() > 0) { |
| return n; |
| } |
| return URIUtil.toUnencodedString(getLocation()); |
| } |
| |
| /* |
| * overridden to lazily fetch repository |
| * (non-Javadoc) |
| * @see org.eclipse.equinox.internal.provisional.p2.ui.query.QueriedElement#getQueryable() |
| */ |
| public IQueryable<?> getQueryable() { |
| if (queryable == null) |
| queryable = getRepository(new NullProgressMonitor()); |
| return queryable; |
| } |
| |
| public IMetadataRepository getRepository(IProgressMonitor monitor) { |
| try { |
| return getMetadataRepository(monitor); |
| } catch (ProvisionException e) { |
| getProvisioningUI().getRepositoryTracker().reportLoadFailure(location, e); |
| } catch (OperationCanceledException e) { |
| // nothing to report |
| } |
| return null; |
| } |
| |
| private IMetadataRepository getMetadataRepository(IProgressMonitor monitor) throws ProvisionException { |
| if (queryable == null) { |
| queryable = getProvisioningUI().loadMetadataRepository(location, false, monitor); |
| } |
| return (IMetadataRepository) queryable; |
| |
| } |
| |
| /* |
| * overridden to check whether url is specified rather |
| * than loading the repo via getQueryable() |
| * (non-Javadoc) |
| * @see org.eclipse.equinox.internal.provisional.p2.ui.query.QueriedElement#knowsQueryable() |
| */ |
| public boolean knowsQueryable() { |
| return location != null; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.equinox.internal.provisional.p2.ui.model.RepositoryElement#getURL() |
| */ |
| public URI getLocation() { |
| return location; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * @see org.eclipse.equinox.internal.provisional.p2.ui.model.RepositoryElement#getName() |
| */ |
| public String getName() { |
| if (name == null) { |
| name = getMetadataRepositoryManager().getRepositoryProperty(location, IRepository.PROP_NICKNAME); |
| if (name == null) |
| name = getMetadataRepositoryManager().getRepositoryProperty(location, IRepository.PROP_NAME); |
| if (name == null) |
| name = ""; //$NON-NLS-1$ |
| } |
| return name; |
| } |
| |
| public void setNickname(String name) { |
| this.name = name; |
| } |
| |
| public void setLocation(URI location) { |
| this.location = location; |
| setQueryable(null); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * @see org.eclipse.equinox.internal.provisional.p2.ui.model.RepositoryElement#getDescription() |
| */ |
| public String getDescription() { |
| if (getProvisioningUI().getRepositoryTracker().hasNotFoundStatusBeenReported(location)) |
| return ProvUIMessages.RepositoryElement_NotFound; |
| String description = getMetadataRepositoryManager().getRepositoryProperty(location, IRepository.PROP_DESCRIPTION); |
| if (description == null) |
| return ""; //$NON-NLS-1$ |
| return description; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.equinox.internal.provisional.p2.ui.model.RepositoryElement#isEnabled() |
| */ |
| public boolean isEnabled() { |
| return isEnabled; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.equinox.internal.provisional.p2.ui.model.IRepositoryElement#setEnabled(boolean) |
| */ |
| public void setEnabled(boolean enabled) { |
| isEnabled = enabled; |
| } |
| |
| /* |
| * Overridden to check whether a repository instance has already been loaded. |
| * This is necessary to prevent background loading of an already loaded repository |
| * by the DeferredTreeContentManager, which will add redundant children to the |
| * viewer. |
| * see https://bugs.eclipse.org/bugs/show_bug.cgi?id=229069 |
| * see https://bugs.eclipse.org/bugs/show_bug.cgi?id=226343 |
| * (non-Javadoc) |
| * @see org.eclipse.equinox.internal.provisional.p2.ui.query.QueriedElement#hasQueryable() |
| */ |
| public boolean hasQueryable() { |
| if (queryable != null) |
| return true; |
| if (location == null) |
| return false; |
| IMetadataRepositoryManager manager = getMetadataRepositoryManager(); |
| if (manager == null || !(manager instanceof MetadataRepositoryManager)) |
| return false; |
| IMetadataRepository repo = ((MetadataRepositoryManager) manager).getRepository(location); |
| if (repo == null) |
| return false; |
| queryable = repo; |
| return true; |
| } |
| |
| public Policy getPolicy() { |
| Object parent = getParent(this); |
| if (parent == null) |
| return super.getPolicy(); |
| if (parent instanceof QueriedElement) |
| return ((QueriedElement) parent).getPolicy(); |
| return getProvisioningUI().getPolicy(); |
| } |
| |
| public String toString() { |
| StringBuffer result = new StringBuffer(); |
| result.append("Metadata Repository Element - "); //$NON-NLS-1$ |
| result.append(URIUtil.toUnencodedString(location)); |
| if (hasQueryable()) |
| result.append(" (loaded)"); //$NON-NLS-1$ |
| else |
| result.append(" (not loaded)"); //$NON-NLS-1$ |
| return result.toString(); |
| } |
| |
| IMetadataRepositoryManager getMetadataRepositoryManager() { |
| return ProvUI.getMetadataRepositoryManager(getProvisioningUI().getSession()); |
| } |
| |
| /** |
| * MetadataRepositoryElements can sometimes be roots and sometimes children. |
| * When they are roots the should have a ui set directly. As children they should |
| * defer to the parent to get the ui. |
| */ |
| public ProvisioningUI getProvisioningUI() { |
| ProvisioningUI ui = super.getProvisioningUI(); |
| if (ui != null) |
| return ui; |
| Object parent = getParent(this); |
| if (parent != null && parent instanceof QueriedElement) |
| return ((QueriedElement) parent).getProvisioningUI(); |
| // if all else fails get the global UI. This should not really happen but |
| // we need to account for some possible historical cases. |
| return ProvisioningUI.getDefaultUI(); |
| } |
| } |