Skip to main content
summaryrefslogtreecommitdiffstats
blob: fc545bca88441451e555cab7184995035232faf7 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
/*******************************************************************************
 * Copyright (c) 2004, 2007 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.ui.internal.intro.impl.model.loader;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.eclipse.ui.internal.intro.impl.model.AbstractIntroPage;
import org.eclipse.ui.internal.intro.impl.model.IntroContentProvider;
import org.eclipse.ui.internal.intro.impl.util.Log;
import org.eclipse.ui.intro.config.IIntroContentProvider;
import org.eclipse.ui.intro.config.IIntroContentProviderSite;

/**
 * Class for handling/caching all the loaded Intro Content providers, from all loaded models. <br>
 * <br />
 * Design notes:
 * <ul>
 * <li>content providers are only ever created once. The init method is only called once, and so
 * this is why they need to be cached.</li>
 * <li>Content provider ids are used as keys in the hashtable, and their corresponding wrapper
 * classes as values.</li>
 * <li>In the case of HTML presentation, html is cached and so model is not consuloted when we need
 * to redisplay a page. When content provider asks for a reflow, the page is removed from HTML cache
 * and intro model is consulted again. This is when the calls happen to this class.</li>
 * <li>In the case of SWT presentation, same design. SWT pages are cached in a page book. When a
 * content provider needs to refresh a page, the page is removed from the page book and recreated
 * from intro model.</li>
 * </ul>
 */

public class ContentProviderManager {

	// singleton instance. Can be retrieved from here or from the Intro Plugin.
	private static ContentProviderManager inst = new ContentProviderManager();


	// Holds all created content providers, to prevent the need to recreate the
	// class on each navigation. Key is the contentProvider id, value
	// is a wrapper class to hold the actual Intro content provider instance and
	// the intro page that holds it.
	private Map<String, ContentProviderWrapper> contentProviders = new HashMap<>();


	class ContentProviderWrapper {

		IIntroContentProvider provider;
		AbstractIntroPage parentPage;

		ContentProviderWrapper(IIntroContentProvider provider, AbstractIntroPage parentPage) {
			this.provider = provider;
			this.parentPage = parentPage;
		}

		IIntroContentProvider getIIntroContentProvider() {
			return provider;
		}

		AbstractIntroPage getParentPage() {
			return parentPage;
		}
	}



	/*
	 * Prevent creation.
	 */
	protected ContentProviderManager() {
		// do nothing
	}

	/**
	 * @return Returns the inst.
	 */
	public static ContentProviderManager getInst() {
		return inst;
	}

	/**
	 * Retrieve an existing content provider class, or null if never created before.
	 *
	 * @param provider
	 * @return
	 */
	public IIntroContentProvider getContentProvider(IntroContentProvider provider) {
		// safe to cast since we know the object class in table.
		ContentProviderWrapper providerWrapper = (ContentProviderWrapper) contentProviders.get(provider
				.getId());
		if (providerWrapper == null)
			// return null if provider has not been created yet.
			return null;
		IIntroContentProvider providerClass = providerWrapper.getIIntroContentProvider();
		return providerClass;
	}

	/**
	 * Tries to create an intro content provider class. may return null if creation fails. This will
	 * be logged.
	 *
	 * @param provider
	 * @param site
	 * @return
	 */
	public IIntroContentProvider createContentProvider(IntroContentProvider provider,
			IIntroContentProviderSite site) {

		// the content provider has never been created before. Create and cache
		// one.
		String pluginId = (provider.getPluginId() != null) ? provider.getPluginId() : provider.getBundle()
				.getSymbolicName();
		Object aClass = ModelLoaderUtil.createClassInstance(pluginId, provider.getClassName());
		IIntroContentProvider providerClass = null;
		if (aClass != null && aClass instanceof IIntroContentProvider) {
			providerClass = ((IIntroContentProvider) aClass);
			providerClass.init(site);
			if (provider.getId() != null) {
				// cache only when an id is defined.
				ContentProviderWrapper wrapper = new ContentProviderWrapper(providerClass, provider
						.getParentPage());
				contentProviders.put(provider.getId(), wrapper);
			}
		} else
			Log.warning("Failed to create Intro model content provider: " //$NON-NLS-1$
					+ provider.getClassName());
		return providerClass;
	}


	public AbstractIntroPage getContentProviderParentPage(IIntroContentProvider provider) {
		for (ContentProviderWrapper wrapper : contentProviders.values()) {
			boolean foundKey = wrapper.getIIntroContentProvider().equals(provider) ? true : false;
			if (foundKey) {
				return wrapper.getParentPage();
			}
		}
		return null;
	}

	public void clear() {
		for (Iterator it = contentProviders.values().iterator(); it.hasNext();) {
			ContentProviderWrapper providerWrapper = (ContentProviderWrapper) it.next();
			IIntroContentProvider provider = providerWrapper.getIIntroContentProvider();
			provider.dispose();
		}
		contentProviders.clear();
		if (Log.logInfo)
			Log.info("Cleared Intro model content providers"); //$NON-NLS-1$
	}


}

Back to the top