/******************************************************************************* * Copyright (c) 2004, 2008 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 *******************************************************************************/ package net.sf.vex.editor.config; import java.io.IOException; import java.io.Serializable; import java.net.URL; import java.text.MessageFormat; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import net.sf.vex.editor.VexPlugin; import org.eclipse.core.runtime.IStatus; /** * A plugin or plugin project that contributes ConfigItems. This class and all * configuration items added to it must be serializable, since it is persisted * across Vex invocations due to the expense of reparsing the configuration * items. */ public abstract class ConfigSource implements Serializable { /** * Adds the given item to the configuration. * @param item ConfigItem to be added. */ public void addItem(ConfigItem item) { this.items.add(item); } /** * Creates a configuration item and adds it to this configuration. * If the given extension point does not have a factory registered * in VexPlugin, 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 */ public ConfigItem addItem( String extensionPoint, String simpleIdentifier, String name, IConfigElement[] configElements) throws IOException { IConfigItemFactory factory = ConfigRegistry.getInstance().getConfigItemFactory(extensionPoint); if (factory != null) { ConfigItem item = factory.createItem(this, configElements); item.setSimpleId(simpleIdentifier); item.setName(name); this.addItem(item); return item; } else { return null; } } /** * Removes the given item from the configuration. * @param item ConfigItem to be removed. */ public void remove(ConfigItem item) { items.remove(item); } /** * Remove all items from this configuration. */ public void removeAllItems() { this.items.clear(); } /** * Remove all parsed resources from this configuration. */ public void removeAllResources() { this.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(String uri) { this.parsedResources.remove(uri); // TODO Respect secondary resources } /** * Returns a list of all items in this configuration. */ public List getAllItems() { return items; } /** * Returns all ConfigItems of the given type registered with this * configuration. * @param type The type of ConfigItem to return. */ public Collection getAllItems(String type) { List items = new ArrayList(); for (Iterator it = this.items.iterator(); it.hasNext();) { ConfigItem item = (ConfigItem) it.next(); if (item.getExtensionPointId().equals(type)) { items.add(item); } } 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(String simpleId) { for (Iterator it = this.items.iterator(); it.hasNext();) { ConfigItem item = (ConfigItem) it.next(); 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 resourcePath Path of the resource. */ public ConfigItem getItemForResource(String resourcePath) { for (Iterator it = this.items.iterator(); it.hasNext();) { ConfigItem item = (ConfigItem) it.next(); if (item.getResourcePath().equals(resourcePath)) { 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(String uri) { return this.parsedResources.get(uri); } /** * Returns the unique identifier of this configuration. This is the same * as the ID of the plugin that defines the configuration. */ public String getUniqueIdentifer() { return this.id; } /** * Returns all ConfigItems of the given type for which isValid returns * true. * @param type The type of ConfigItem to return. */ public Collection getValidItems(String type) { Collection allItems = this.getAllItems(type); List validItems = new ArrayList(); for (Iterator it = allItems.iterator(); it.hasNext();) { ConfigItem item = (ConfigItem) it.next(); // FIXME auskommentier cp // if (item.isValid()) { validItems.add(item); // } } return validItems; } /** * Returns true if there are no items in this configuration. */ public boolean isEmpty() { return this.items.isEmpty(); } /** * Parses all resources required by the registered items. * @param problemHandler Handler for build problems. May be null. */ public void parseResources(IBuildProblemHandler problemHandler) { for (Iterator it = this.items.iterator(); it.hasNext();) { ConfigItem item = (ConfigItem) it.next(); String uri = item.getResourcePath(); if (!this.parsedResources.containsKey(uri)) { IConfigItemFactory factory = ConfigRegistry.getInstance().getConfigItemFactory(item.getExtensionPointId()); Object parsedResource; try { parsedResource = factory.parseResource(this.getBaseUrl(), uri, problemHandler); this.parsedResources.put(uri, parsedResource); } catch (IOException ex) { String message = MessageFormat.format( Messages.getString("ConfigSource.errorParsingUri"), new Object[] { uri }); VexPlugin.getInstance().log(IStatus.ERROR, message, ex); //$NON-NLS-1$ } } } } /** * Sets the unique identifier of this configuration. * @param id New identifier for this configuration. */ public void setUniqueIdentifer(String id) { this.id = id; } //==================================================== PRIVATE // Globally-unique identifier of this configuration // == the plugin id. private String id; // all config items in this configuration private List items = new ArrayList(); // map String URI => parsed resource private Map parsedResources = new HashMap(); }