blob: 36b81372a1232953beedbe3aa74654c64938574b [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2010, 2015 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.help.internal.base.scope;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.help.IIndexEntry;
import org.eclipse.help.IIndexEntry2;
import org.eclipse.help.IIndexSee;
import org.eclipse.help.IToc;
import org.eclipse.help.ITopic;
import org.eclipse.help.IUAElement;
import org.eclipse.help.base.AbstractHelpScope;
import org.eclipse.help.internal.UAElement;
import org.eclipse.help.internal.index.Index;
import org.eclipse.help.internal.index.IndexSee;
/**
* Utilities to test for enabled topics, index entries etc.
*/
public class ScopeUtils {
/*
* Function to determine whether a topic should be shown in the toc.
* For hierarchical scopes the element itself must be in scope.
* For non hierarchical scopes if any child is in scope the element should show.
* A toc with no in scope topics does not display
*/
public static boolean showInTree(IToc toc, AbstractHelpScope scope) {
if (scope.isHierarchicalScope() && !scope.inScope(toc)) {
return false;
}
return hasInScopeDescendent(toc, scope);
}
/*
* Function to determine whether a topic should be shown in the toc.
* For hierarchical scopes the element itself must be in scope.
* For non hierarchical scopes if any child is in scope the element should show.
* Leaf topics with no href do not show in the toc
*/
public static boolean showInTree(ITopic topic, AbstractHelpScope scope) {
if (scope.inScope(topic)) {
return (topic.getHref() != null) || hasInScopeDescendent(topic, scope);
}
return !scope.isHierarchicalScope() && hasInScopeDescendent(topic, scope);
}
/*
* Function to determine whether an entry should be shown in the index.
* For hierarchical scopes the element itself must be in scope.
* For non hierarchical scopes if any child is in scope the element should show.
* An entry with no topic descendants does not display
*/
public static boolean showInTree(IIndexEntry entry, AbstractHelpScope scope) {
if (scope.isHierarchicalScope() && !scope.inScope(entry)) {
return false;
}
return hasInScopeDescendent(entry, scope);
}
/*
* Returns true if one of the children meets the conditions
* necessary to be shown in the Toc tree
*/
public static boolean hasInScopeDescendent(ITopic topic, AbstractHelpScope scope) {
ITopic[] subtopics = topic.getSubtopics();
for (int i = 0; i < subtopics.length; i++) {
if (showInTree(subtopics[i], scope)) {
return true;
}
}
return false;
}
/*
* Returns true if one of the children meets the conditions
* necessary to be shown in the Toc tree
*/
public static boolean hasInScopeDescendent(IToc toc, AbstractHelpScope scope) {
ITopic[] topics = toc.getTopics();
for (int i = 0; i < topics.length; i++) {
if (showInTree(topics[i], scope)) {
return true;
}
}
return false;
}
/*
* Returns true if one of the children meets the conditions
* necessary to be shown in the Index
*/
public static boolean hasInScopeDescendent(IIndexEntry entry,
AbstractHelpScope scope) {
ITopic[] topics = entry.getTopics();
for (int t = 0; t < topics.length; t++) {
if (showInTree(topics[t], scope)) {
return true;
}
}
IIndexEntry[] entries = entry.getSubentries();
for (int e = 0; e < entries.length; e++) {
if (showInTree(entries[e], scope)) {
return true;
}
}
if (entry instanceof IIndexEntry2) {
IIndexSee[] sees = ((IIndexEntry2)entry).getSees();
for (int s = 0; s < sees.length; s++) {
if (showInTree(sees[s], scope)) {
return true;
}
}
}
return false;
}
public static boolean hasInScopeTarget(IIndexSee see, AbstractHelpScope scope) {
if (see instanceof IndexSee) {
IndexSee indexSee = (IndexSee)see;
UAElement ancestor = indexSee.getParentElement();
while (!(ancestor instanceof Index)) {
if (ancestor == null) {
return true;
}
ancestor = ancestor.getParentElement();
}
IIndexEntry target = ((Index)ancestor).getSeeTarget(indexSee);
if (target == null) {
return false;
}
return showInTree(target, scope);
}
return false;
}
public static boolean showInTree(IIndexSee see, AbstractHelpScope scope) {
if (scope.isHierarchicalScope() && !scope.inScope(see)) {
return false;
}
if (see instanceof IndexSee) {
IndexSee indexSee = (IndexSee)see;
UAElement ancestor = indexSee.getParentElement();
while (!(ancestor instanceof Index)) {
if (ancestor == null) {
return true;
}
ancestor = ancestor.getParentElement();
}
IIndexEntry target = ((Index)ancestor).getSeeTarget(indexSee);
if (target == null) {
return false;
}
return showInTree(target, scope);
}
return false;
}
/**
* Filter out any disabled entries from an array
* @param entries an array of entries
* @param scope
* @return an array containing only those entries which are enabled
*/
public static IIndexEntry[] inScopeEntries(IIndexEntry[] entries, AbstractHelpScope scope) {
for (int i=0;i<entries.length;++i) {
if (!scope.inScope(entries[i])) {
List<IIndexEntry> list = new ArrayList<>(entries.length);
for (int j=0;j<entries.length;++j) {
if (j < i || scope.inScope(entries[j])) {
list.add(entries[j]);
}
}
return list.toArray(new IIndexEntry[list.size()]);
}
}
return entries;
}
/**
* Filter out any disabled topics from an array
* @param topics an array of topics
* @param scope
* @return an array containing only those topics which are enabled
*/
public static ITopic[] inScopeTopics(ITopic[] topics, AbstractHelpScope scope) {
for (int i=0;i<topics.length;++i) {
if (!scope.inScope(topics[i])) {
List<ITopic> list = new ArrayList<>(topics.length);
for (int j=0;j<topics.length;++j) {
if (j < i || scope.inScope(topics[j])) {
list.add(topics[j]);
}
}
return list.toArray(new ITopic[list.size()]);
}
}
return topics;
}
public static boolean hasInScopeChildren(IUAElement element,
AbstractHelpScope scope) {
if (element instanceof IToc) {
return hasInScopeDescendent((IToc)element, scope);
}
if (element instanceof ITopic) {
return hasInScopeDescendent((ITopic)element, scope);
}
if (element instanceof IIndexEntry) {
return hasInScopeDescendent((IIndexEntry) element, scope);
}
if (element instanceof IIndexSee) {
return hasInScopeTarget((IIndexSee) element, scope);
}
return false;
}
}