1 /*******************************************************************************
2  * Copyright (c) 2006, 2016 IBM Corporation and others.
3  *
4  * This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License 2.0
6  * which accompanies this distribution, and is available at
7  * https://www.eclipse.org/legal/epl-2.0/
8  *
9  * SPDX-License-Identifier: EPL-2.0
10  *
11  * Contributors: IBM Corporation - initial API and implementation
12  *******************************************************************************/
13 package org.eclipse.help.internal.toc;
14 
15 import java.util.HashMap;
16 import java.util.Map;
17 
18 import org.eclipse.core.expressions.IEvaluationContext;
19 import org.eclipse.help.ICriteria;
20 import org.eclipse.help.IToc;
21 import org.eclipse.help.IToc2;
22 import org.eclipse.help.ITocContribution;
23 import org.eclipse.help.ITopic;
24 import org.eclipse.help.ITopic2;
25 import org.eclipse.help.IUAElement;
26 import org.eclipse.help.internal.UAElement;
27 import org.w3c.dom.Element;
28 
29 public class Toc extends UAElement implements IToc2 {
30 
31 	public static final String NAME = "toc"; //$NON-NLS-1$
32 	public static final String ATTRIBUTE_LABEL = "label"; //$NON-NLS-1$
33 	public static final String ATTRIBUTE_HREF = "href"; //$NON-NLS-1$
34 	public static final String ATTRIBUTE_TOPIC = "topic"; //$NON-NLS-1$
35 	public static final String ATTRIBUTE_LINK_TO = "link_to"; //$NON-NLS-1$
36 	public static final String ATTRIBUTE_ID = "id"; //$NON-NLS-1$
37 	public static final String ATTRIBUTE_ICON = "icon"; //$NON-NLS-1$
38 	public static final String ATTRIBUTE_SORT = "sort"; //$NON-NLS-1$
39 
40 	private ITocContribution contribution;
41 	private ITopic topic;
42 	private Map<String, ITopic> href2TopicMap;
43 
Toc(IToc src)44 	public Toc(IToc src) {
45 		super(NAME, src);
46 		setHref(src.getHref());
47 		setLabel(src.getLabel());
48 		ITopic topic = src.getTopic(null);
49 		if (topic != null) {
50 			setTopic(topic.getHref());
51 		}
52 		appendChildren(src.getChildren());
53 	}
54 
Toc(Element src)55 	public Toc(Element src) {
56 		super(src);
57 	}
58 
59 	/*
60 	 * Creates a mapping of all topic hrefs to ITopics.
61 	 */
createHref2TopicMap()62 	private Map<String, ITopic> createHref2TopicMap() {
63 		Map<String, ITopic> map = new HashMap<>();
64 		if (topic != null) {
65 			map.put(topic.getHref(), topic);
66 		}
67 		ITopic[] topics = getTopics();
68 		for (int i = 0; i < topics.length; ++i) {
69 			createHref2TopicMapAux(map, topics[i]);
70 		}
71 		return map;
72 	}
73 
74 	/*
75 	 * Creates a mapping of all topic hrefs to ITopics under the given ITopic and stores in the
76 	 * given Map.
77 	 */
createHref2TopicMapAux(Map<String, ITopic> map, ITopic topic)78 	private void createHref2TopicMapAux(Map<String, ITopic> map, ITopic topic) {
79 		String href = topic.getHref();
80 		if (href != null) {
81 			map.put(href, topic);
82 			int anchorIx = href.lastIndexOf("#"); //$NON-NLS-1$
83 			if (anchorIx >= 0) { // anchor exists, drop it and add href again to map
84 				String simpleHref = href.substring(0, anchorIx);
85 				if (!map.containsKey(simpleHref)) {
86 					map.put(simpleHref, topic);
87 				}
88 			}
89 		}
90 		ITopic[] subtopics = topic.getSubtopics();
91 		if (subtopics != null) {
92 			for (int i = 0; i < subtopics.length; ++i) {
93 				if (subtopics[i] != null) {
94 					createHref2TopicMapAux(map, subtopics[i]);
95 				}
96 			}
97 		}
98 	}
99 
100 	@Override
getHref()101 	public String getHref() {
102 		return getAttribute(ATTRIBUTE_HREF);
103 	}
104 
105 	@Override
getIcon()106 	public String getIcon() {
107 		return getAttribute(ATTRIBUTE_ICON);
108 	}
109 
110 	@Override
isSorted()111 	public boolean isSorted() {
112 		return "true".equalsIgnoreCase(getAttribute(ATTRIBUTE_SORT)); //$NON-NLS-1$
113 	}
114 
115 	/*
116 	 * Returns a mapping of all topic hrefs to ITopics.
117 	 */
getHref2TopicMap()118 	private Map<String, ITopic> getHref2TopicMap() {
119 		if (href2TopicMap == null) {
120 			href2TopicMap = createHref2TopicMap();
121 		}
122 		return href2TopicMap;
123 	}
124 
125 	@Override
getLabel()126 	public String getLabel() {
127 		return getAttribute(ATTRIBUTE_LABEL);
128 	}
129 
getLinkTo()130 	public String getLinkTo() {
131 		return getAttribute(ATTRIBUTE_LINK_TO);
132 	}
133 
getTopic()134 	public String getTopic() {
135 		return getAttribute(ATTRIBUTE_TOPIC);
136 	}
137 
138 	@Override
getTopic(String href)139 	public ITopic getTopic(String href) {
140 		if (href == null) {
141 			if (topic == null) {
142 				topic = new ITopic2() {
143 
144 					@Override
145 					public String getHref() {
146 						return getTopic();
147 					}
148 
149 					@Override
150 					public String getLabel() {
151 						return Toc.this.getLabel();
152 					}
153 
154 					@Override
155 					public ITopic[] getSubtopics() {
156 						return getTopics();
157 					}
158 
159 					@Override
160 					public boolean isEnabled(IEvaluationContext context) {
161 						return Toc.this.isEnabled(context);
162 					}
163 
164 					@Override
165 					public IUAElement[] getChildren() {
166 						return new IUAElement[0];
167 					}
168 
169 					@Override
170 					public ICriteria[] getCriteria() {
171 						return Toc.this.getCriteria();
172 					}
173 
174 					@Override
175 					public String getIcon() {
176 						return null;
177 					}
178 
179 					@Override
180 					public boolean isSorted() {
181 						return false;
182 					}
183 				};
184 			}
185 			return topic;
186 		} else {
187 			return getHref2TopicMap().get(href);
188 		}
189 	}
190 
191 	@Override
getTopics()192 	public ITopic[] getTopics() {
193 		return getChildren(ITopic.class);
194 	}
195 
196 	@Override
getCriteria()197 	public ICriteria[] getCriteria() {
198 		return getChildren(ICriteria.class);
199 	}
200 
setLabel(String label)201 	public void setLabel(String label) {
202 		setAttribute(ATTRIBUTE_LABEL, label);
203 	}
204 
setLinkTo(String linkTo)205 	public void setLinkTo(String linkTo) {
206 		setAttribute(ATTRIBUTE_LINK_TO, linkTo);
207 	}
208 
setTopic(String href)209 	public void setTopic(String href) {
210 		setAttribute(ATTRIBUTE_TOPIC, href);
211 	}
212 
setHref(String href)213 	public void setHref(String href) {
214 		setAttribute(ATTRIBUTE_HREF, href);
215 	}
216 
getTocContribution()217 	public ITocContribution getTocContribution() {
218 		return contribution;
219 	}
220 
setTocContribution(ITocContribution contribution)221 	public void setTocContribution(ITocContribution contribution) {
222 		this.contribution = contribution;
223 	}
224 
225 }
226