Skip to main content
aboutsummaryrefslogtreecommitdiffstats
blob: b284ea1776ac78af7ec5cd201cf49b7b2005daef (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
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
/*******************************************************************************
 * Copyright (c) 2004, 2010 John Krasnay 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:
 *     John Krasnay - initial API and implementation
 *     Igor Jacy Lino Campista - Java 5 warnings fixed (bug 311325)
 *******************************************************************************/
package org.eclipse.wst.xml.vex.ui.internal.config;

import java.io.IOException;
import java.net.URL;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.wst.common.uriresolver.internal.provisional.URIResolver;
import org.eclipse.wst.common.uriresolver.internal.provisional.URIResolverPlugin;
import org.eclipse.wst.xml.vex.ui.internal.VexPlugin;

/**
 * Base class for an installed bundle or plug-in project that contributes
 * ConfigItems.
 */
public abstract class ConfigSource {

	private static final IConfigItemFactory[] CONFIG_ITEM_FACTORIES = new IConfigItemFactory[] { new DoctypeFactory(), new StyleFactory() };
	
	// Globally-unique identifier of this configuration == the plugin id.
	private final String id;

	// all config items in this configuration
	private final List<ConfigItem> items = new ArrayList<ConfigItem>();

	// map String URI => parsed resource
	private final Map<String, Object> parsedResources = new HashMap<String, Object>();

	protected static IConfigItemFactory getConfigItemFactory(final String extensionPointId) {
		for (final IConfigItemFactory factory : CONFIG_ITEM_FACTORIES)
			if (factory.getExtensionPointId().equals(extensionPointId))
				return factory;
		return null;
	}
	
	public ConfigSource(final String id) {
		this.id = id;
	}

	/**
	 * Adds the given item to this configuration.
	 * 
	 * @param item
	 *            ConfigItem to be added.
	 */
	public void addItem(final ConfigItem item) {
		items.add(item);
		parseResources(null);
	}

	/**
	 * Creates a configuration item and adds it to this configuration. If the
	 * given extension point does not have a factory registered, no* action is 
	 * taken and null is returned.
	 * 
	 * @param extensionPoint
	 *            Extension point of the item to be added.
	 * @param simpleIdentifier
	 *            Simple (i.e. no dots) identifier of the item.
	 * @param name
	 *            Name of the item.
	 * @param configElements
	 *            Array of IConfigElement objects representing the item's
	 *            settings.
	 * @return The newly created ConfigItem, or null if extensionPoint is not
	 *         recognized.
	 * @throws IOException
	 */
	protected ConfigItem addItem(final String extensionPoint, final String simpleIdentifier, final String name, final IConfigElement[] configElements)
			throws IOException {
		final IConfigItemFactory factory = getConfigItemFactory(extensionPoint);
		if (factory == null)
			return null;
		final ConfigItem item = factory.createItem(this, configElements);
		item.setSimpleId(simpleIdentifier);
		item.setName(name);
		this.addItem(item);
		return item;

	}

	/**
	 * Removes the given item from this configuration.
	 * 
	 * @param item
	 *            ConfigItem to be removed.
	 */
	public void remove(final ConfigItem item) {
		items.remove(item);
	}

	/**
	 * Remove all items from this configuration.
	 */
	public void removeAllItems() {
		items.clear();
	}

	/**
	 * Remove all parsed resources from this configuration.
	 */
	public void removeAllResources() {
		parsedResources.clear();
	}

	/**
	 * Remove the resource associated with the given URI from the resource
	 * cache. The factory must handle any of the following scenarios.
	 * 
	 * <ul>
	 * <li>The URI represents the primary resource associated with a
	 * configuration item.</li>
	 * <li>The URI is a secondary resource associated with a primary resource.
	 * In this case the primary resource is removed.</li>
	 * <li>The URI has nothing to do with a configuration item, in which case no
	 * action is taken.</li>
	 * </ul>
	 * 
	 * To fully implement this method, the factory must interact with the parser
	 * and track which secondary resources are associated with which primaries.
	 * 
	 * @param uri
	 *            Relative URI of the resource to remove.
	 */
	public void removeResource(final String uri) {
		parsedResources.remove(uri); // TODO Respect secondary resources
	}

	/**
	 * Returns a list of all items in this configuration.
	 */
	public List<ConfigItem> getAllItems() {
		return items;
	}

	/**
	 * Returns the base URL of this factory. This is used to resolve relative
	 * URLs in config items
	 */
	public abstract URL getBaseUrl();

	/**
	 * Returns a particular item from the configuration. Returns null if no
	 * matching item could be found.
	 * 
	 * @param simpleId
	 *            Simple ID of the item to return.
	 */
	public ConfigItem getItem(final String simpleId) {
		for (final ConfigItem item : items)
			if (item.getSimpleId() != null && item.getSimpleId().equals(simpleId))
				return item;
		return null;
	}

	/**
	 * Returns the item for the resource with the given path relative to the
	 * plugin or project. May return null if no such item exists.
	 * 
	 * @param resource
	 *            Path of the resource.
	 */
	public ConfigItem getItemForResource(final IResource resource) {
		for (final ConfigItem item : items)
			if (item.getResourcePath().equals(resource.getLocationURI().toString()))
				return item;
		return null;
	}

	/**
	 * Returns the parsed resource object for the given URI, or null of none
	 * exists.
	 * 
	 * @param uri
	 *            URI of the resource, relative to the base URL of this
	 *            configuration.
	 */
	public Object getParsedResource(final String uri) {
		return parsedResources.get(uri);
	}

	/**
	 * Returns the unique identifier of this configuration.
	 */
	public String getUniqueIdentifer() {
		return id;
	}

	/**
	 * Returns all ConfigItems of the given type for which isValid returns true.
	 * 
	 * @param extensionPointId
	 *            The type of ConfigItem to return.
	 */
	public Collection<ConfigItem> getValidItems(final String extensionPointId) {
		final List<ConfigItem> result = new ArrayList<ConfigItem>();
		for (final ConfigItem item : items)
			if (item.getExtensionPointId().equals(extensionPointId) && item.isValid())
				result.add(item);
		return result;
	}

	/**
	 * Returns true if there are no items in this configuration.
	 */
	public boolean isEmpty() {
		return items.isEmpty();
	}

	/**
	 * Parses all resources required by the registered items.
	 * 
	 * @param problemHandler
	 *            Handler for build problems. May be null.
	 */
	public void parseResources(final IBuildProblemHandler problemHandler) {
		parsedResources.clear();
		for (final ConfigItem item : items) {
			final String uri = item.getResourcePath();
			if (!parsedResources.containsKey(uri)) {
				final IConfigItemFactory factory = getConfigItemFactory(item.getExtensionPointId());
				try {
					final Object parsedResource = factory.parseResource(getBaseUrl(), uri, problemHandler);
					if (parsedResource != null)
						parsedResources.put(uri, parsedResource);
				} catch (final IOException ex) {
					final String message = MessageFormat.format(Messages.getString("ConfigSource.errorParsingUri"), new Object[] { uri });
					VexPlugin.getInstance().log(IStatus.ERROR, message, ex);
				}
			}
		}
	}
	
	public String resolve(final String publicId, final String systemId) {
		URIResolver uriResolver = URIResolverPlugin.createResolver();
		return uriResolver.resolve(getBaseUrl().toString(), publicId, systemId);
	}

}

Back to the top