Package at.bestsolution.efxclipse.text.editor.text.templates

Source Code of at.bestsolution.efxclipse.text.editor.text.templates.ContributionContextTypeRegistry

package at.bestsolution.efxclipse.text.editor.text.templates;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;

import org.eclipse.jface.text.templates.TemplateContextType;
import org.eclipse.jface.text.templates.TemplateVariableResolver;

import at.bestsolution.efxclipse.text.editor.internal.TextEditorPlugin;
import at.bestsolution.efxclipse.text.jface.templates.ContextTypeRegistry;



/**
* A registry for context types. Editor implementors will usually instantiate a
* registry and configure the context types available in their editor.
* <code>ContextType</code>s can be added either directly using
* {@link #addContextType(TemplateContextType)} or by instantiating and adding a
* contributed context type using {@link #addContextType(String)}.
*
* @since 3.0
*/
public class ContributionContextTypeRegistry extends ContextTypeRegistry {

  /* extension point string literals */
  private static final String TEMPLATES_EXTENSION_POINT= "org.eclipse.ui.editors.templates"; //$NON-NLS-1$

  private static final String CONTEXT_TYPE= "contextType"; //$NON-NLS-1$
  private static final String ID= "id"; //$NON-NLS-1$
  private static final String NAME= "name"; //$NON-NLS-1$
  private static final String CLASS= "class"; //$NON-NLS-1$

  private static final String RESOLVER= "resolver"; //$NON-NLS-1$
  private static final String CONTEXT_TYPE_ID= "contextTypeId"; //$NON-NLS-1$
  private static final String DESCRIPTION= "description"; //$NON-NLS-1$
  private static final String TYPE= "type"; //$NON-NLS-1$
  private static final String REGISTRY= "contextTypeRegistry"; //$NON-NLS-1$
  private static final String REGISTRY_ID= "registryId"; //$NON-NLS-1$


  /**
   * Creates a new context type registry and registers all context types contributed for the given
   * registry ID.
   *
   * @param registryId the registry ID
   * @since 3.5
   */
  public ContributionContextTypeRegistry(String registryId) {
    readRegistry(registryId);
  }

  /**
   * Creates a new context type registry.
   * <p>
   * Clients need to enable the desired context types by calling {@link #addContextType(String)}.
   * </p>
   */
  public ContributionContextTypeRegistry() {
  }

  /**
   * Registers all context types contributed for the given registry ID.
   *
   * @param registryId the registry ID
   * @since 3.5
   */
  private void readRegistry(String registryId) {
    Assert.isNotNull(registryId);

    IConfigurationElement[] extensions= getTemplateExtensions();

    for (int i= 0; i < extensions.length; i++) {
      if (extensions[i].getName().equals(REGISTRY)) {
        String id= extensions[i].getAttribute(ID);
        if (registryId.equals(id)) {
          for (int j= 0; j < extensions.length; j++) {
            if (extensions[j].getName().equals(CONTEXT_TYPE)) {
              if (registryId.equals(extensions[j].getAttribute(REGISTRY_ID)))
                addContextType(extensions[j].getAttribute(ID));
            }
          }
          return;
        }

      }
    }

    Assert.isTrue(false, "invalid registry id"); //$NON-NLS-1$
  }

  /**
   * Tries to create a context type given an id. If there is already a context
   * type registered under the given id, nothing happens. Otherwise,
   * contributions to the <code>org.eclipse.ui.editors.templates</code>
   * extension point are searched for the given identifier and the specified
   * context type instantiated if it is found.
   *
   * @param id the id for the context type as specified in XML
   */
  public void addContextType(String id) {
    Assert.isNotNull(id);
    if (getContextType(id) != null)
      return;

    TemplateContextType type= createContextType(id);
    if (type != null)
      addContextType(type);

  }

  /**
   * Tries to create a context type given an id. Contributions to the
   * <code>org.eclipse.ui.editors.templates</code> extension point are
   * searched for the given identifier and the specified context type
   * instantiated if it is found. Any contributed
   * {@link org.eclipse.jface.text.templates.TemplateVariableResolver}s
   * are also instantiated and added to the context type.
   *
   * @param id the id for the context type as specified in XML
   * @return the instantiated and configured context type, or
   *         <code>null</code> if it is not found or cannot be instantiated
   */
  public static TemplateContextType createContextType(String id) {
    Assert.isNotNull(id);

    IConfigurationElement[] extensions= getTemplateExtensions();
    TemplateContextType type;
    try {
      type= createContextType(extensions, id);
      if (type != null) {
        TemplateVariableResolver[] resolvers= createResolvers(extensions, id);
        for (int i= 0; i < resolvers.length; i++)
          type.addResolver(resolvers[i]);
      }
    } catch (CoreException e) {
      TextEditorPlugin.log(e);
      type= null;
    }

    return type;
  }

  private static TemplateContextType createContextType(IConfigurationElement[] extensions, String contextTypeId) throws CoreException {
    for (int i= 0; i < extensions.length; i++) {
      // TODO create half-order over contributions
      if (extensions[i].getName().equals(CONTEXT_TYPE)) {
        String id= extensions[i].getAttribute(ID);
        if (contextTypeId.equals(id))
          return createContextType(extensions[i]);
      }
    }

    return null;
  }

  /**
   * Instantiates the resolvers contributed to the context type with id
   * <code>contextTypeId</code>. If instantiation of one resolver fails,
   * the exception are logged and operation continues.
   *
   * @param extensions the configuration elements to parse
   * @param contextTypeId the id of the context type for which resolvers are
   *        instantiated
   * @return the instantiated resolvers
   */
  private static TemplateVariableResolver[] createResolvers(IConfigurationElement[] extensions, String contextTypeId) {
    List resolvers= new ArrayList();
    for (int i= 0; i < extensions.length; i++) {
      if (extensions[i].getName().equals(RESOLVER)) {
        String declaredId= extensions[i].getAttribute(CONTEXT_TYPE_ID);
        if (contextTypeId.equals(declaredId)) {
          try {
            TemplateVariableResolver resolver= createResolver(extensions[i]);
            if (resolver != null)
              resolvers.add(resolver);
          } catch (CoreException e) {
            TextEditorPlugin.log(e);
          }
        }
      }
    }

    return (TemplateVariableResolver[]) resolvers.toArray(new TemplateVariableResolver[resolvers.size()]);

  }

  private static IConfigurationElement[] getTemplateExtensions() {
    return Platform.getExtensionRegistry().getConfigurationElementsFor(TEMPLATES_EXTENSION_POINT);
  }

  private static TemplateContextType createContextType(IConfigurationElement element) throws CoreException {
    String id= element.getAttribute(ID);
    try {
      TemplateContextType contextType= (TemplateContextType) element.createExecutableExtension(CLASS);
      String name= element.getAttribute(NAME);
      if (name == null)
        name= id;

      if (contextType.getId() == null)
        contextType.setId(id);
      if (contextType.getName() == null)
        contextType.setName(name);

      return contextType;
    } catch (ClassCastException e) {
      throw new CoreException(new Status(IStatus.ERROR, TextEditorPlugin.PLUGIN_ID, IStatus.OK, "extension does not implement " + TemplateContextType.class.getName(), e)); //$NON-NLS-1$
    }
  }

  private static TemplateVariableResolver createResolver(IConfigurationElement element) throws CoreException {
    try {
      String type= element.getAttribute(TYPE);
      if (type != null) {

        TemplateVariableResolver resolver= (TemplateVariableResolver) element.createExecutableExtension(CLASS);
        resolver.setType(type);

        String desc= element.getAttribute(DESCRIPTION);
        resolver.setDescription(desc == null ? "" : desc); //$NON-NLS-1$

        return resolver;
      }
    } catch (ClassCastException e) {
      throw new CoreException(new Status(IStatus.ERROR, TextEditorPlugin.PLUGIN_ID, IStatus.OK, "extension does not implement " + TemplateVariableResolver.class.getName(), e)); //$NON-NLS-1$
    }

    return null;
  }
}
TOP

Related Classes of at.bestsolution.efxclipse.text.editor.text.templates.ContributionContextTypeRegistry

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.