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

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

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

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.PropertyResourceBundle;
import java.util.ResourceBundle;

import org.osgi.framework.Bundle;

import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;


import org.eclipse.jface.text.templates.Template;
import org.eclipse.jface.text.templates.TemplateException;

import at.bestsolution.efxclipse.jface.preferences.IPreferenceStore;
import at.bestsolution.efxclipse.text.editor.internal.TextEditorPlugin;
import at.bestsolution.efxclipse.text.jface.templates.ContextTypeRegistry;
import at.bestsolution.efxclipse.text.jface.templates.persistence.TemplatePersistenceData;
import at.bestsolution.efxclipse.text.jface.templates.persistence.TemplateReaderWriter;
import at.bestsolution.efxclipse.text.jface.templates.persistence.TemplateStore;


/**
* Manages templates. Handles reading default templates contributed via XML and
* user-defined (or overridden) templates stored in the preferences.
* <p>
* Clients may instantiate but not subclass this class.
* </p>
*
* @since 3.0
* @noextend This class is not intended to be subclassed by clients.
*/
public class ContributionTemplateStore extends TemplateStore {
  /* extension point string literals */
  private static final String TEMPLATES_EXTENSION_POINT= "org.eclipse.ui.editors.templates"; //$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 CONTEXT_TYPE_ID= "contextTypeId"; //$NON-NLS-1$
  private static final String DESCRIPTION= "description"; //$NON-NLS-1$
  private static final String AUTO_INSERT= "autoinsert"; //$NON-NLS-1$

  private static final String TEMPLATE= "template"; //$NON-NLS-1$
  private static final String PATTERN= "pattern"; //$NON-NLS-1$

  private static final String INCLUDE= "include"; //$NON-NLS-1$
  private static final String FILE= "file"; //$NON-NLS-1$
  private static final String TRANSLATIONS= "translations"; //$NON-NLS-1$

  /**
   * Creates a new template store.
   *
   * @param store the preference store in which to store custom templates
   *        under <code>key</code>
   * @param key the key into <code>store</code> where to store custom
   *        templates
   */
  public ContributionTemplateStore(IPreferenceStore store, String key) {
    super(store, key);
  }

  /**
   * Creates a new template store with a context type registry. Only templates
   * that specify a context type contained in the registry will be loaded by
   * this store if the registry is not <code>null</code>.
   *
   * @param registry a context type registry, or <code>null</code> if all
   *        templates should be loaded
   * @param store the preference store in which to store custom templates
   *        under <code>key</code>
   * @param key the key into <code>store</code> where to store custom
   *        templates
   */
  public ContributionTemplateStore(ContextTypeRegistry registry, IPreferenceStore store, String key) {
    super(registry, store, key);
  }

  /**
   * Loads the templates contributed via the templates extension point.
   *
   * @throws IOException {@inheritDoc}
   */
  protected void loadContributedTemplates() throws IOException {
    IConfigurationElement[] extensions= getTemplateExtensions();
    Collection contributed= readContributedTemplates(extensions);
    for (Iterator it= contributed.iterator(); it.hasNext();) {
      TemplatePersistenceData data= (TemplatePersistenceData) it.next();
      internalAdd(data);
    }
  }

  private Collection readContributedTemplates(IConfigurationElement[] extensions) throws IOException {
    Collection templates= new ArrayList();
    for (int i= 0; i < extensions.length; i++) {
      if (extensions[i].getName().equals(TEMPLATE))
        createTemplate(templates, extensions[i]);
      else if (extensions[i].getName().equals(INCLUDE)) {
        readIncludedTemplates(templates, extensions[i]);
      }
    }

    return templates;
  }

  private void readIncludedTemplates(Collection templates, IConfigurationElement element) throws IOException {
    String file= element.getAttribute(FILE);
    if (file != null) {
      Bundle plugin = Platform.getBundle(element.getContributor().getName());
      URL url= FileLocator.find(plugin, Path.fromOSString(file), null);
      if (url != null) {
        ResourceBundle bundle= null;
        InputStream bundleStream= null;
        InputStream stream= null;
        try {
          String translations= element.getAttribute(TRANSLATIONS);
          if (translations != null) {
            URL bundleURL= FileLocator.find(plugin, Path.fromOSString(translations), null);
            if (bundleURL != null) {
              bundleStream= bundleURL.openStream();
              bundle= new PropertyResourceBundle(bundleStream);
            }
          }

          stream= new BufferedInputStream(url.openStream());
          TemplateReaderWriter reader= new TemplateReaderWriter();
          TemplatePersistenceData[] datas= reader.read(stream, bundle);
          for (int i= 0; i < datas.length; i++) {
            TemplatePersistenceData data= datas[i];
            if (data.isCustom()) {
              if (data.getId() == null)
                TextEditorPlugin.logErrorMessage(MessageFormat.format(ContributionTemplateMessages.ContributionTemplateStore_ignore_no_id, data.getTemplate().getName()));
              else
                TextEditorPlugin.logErrorMessage(MessageFormat.format(ContributionTemplateMessages.ContributionTemplateStore_ignore_deleted, data.getTemplate().getName()));
            } else if (validateTemplate(data.getTemplate())) {
              templates.add(data);
            }
          }
        } finally {
          try {
            if (bundleStream != null)
              bundleStream.close();
          } catch (IOException x) {
          } finally {
            try {
              if (stream != null)
                stream.close();
            } catch (IOException x) {
            }
          }
        }
      }
    }
  }

  /**
   * Validates a template against the context type registered in the context
   * type registry. Returns always <code>true</code> if no registry is
   * present.
   *
   * @param template the template to validate
   * @return <code>true</code> if validation is successful or no context
   *         type registry is specified, <code>false</code> if validation
   *         fails
   */
  private boolean validateTemplate(Template template) {
    String contextTypeId= template.getContextTypeId();
    if (!contextExists(contextTypeId))
      return false;

    if (getRegistry() != null) {
      try {
        getRegistry().getContextType(contextTypeId).validate(template.getPattern());
      } catch (TemplateException e) {
        TextEditorPlugin.log(MessageFormat.format(ContributionTemplateMessages.ContributionTemplateStore_ignore_validation_failed, template.getName()), e);
        return false;
      }
    }
    return true;
  }

  /**
   * Returns <code>true</code> if a context type id specifies a valid context type
   * or if no context type registry is present.
   *
   * @param contextTypeId the context type id to look for
   * @return <code>true</code> if the context type specified by the id
   *         is present in the context type registry, or if no registry is
   *         specified
   */
  private boolean contextExists(String contextTypeId) {
    return contextTypeId != null && (getRegistry() == null || getRegistry().getContextType(contextTypeId) != null);
  }

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

  private void createTemplate(Collection map, IConfigurationElement element) {
    String contextTypeId= element.getAttribute(CONTEXT_TYPE_ID);
    // log failures since extension point id and name are mandatory
    if (contextExists(contextTypeId)) {
      String id= element.getAttribute(ID);
      if (isValidTemplateId(id)) {

        String name= element.getAttribute(NAME);
        if (name != null) {

          String pattern= element.getChildren(PATTERN)[0].getValue();
          if (pattern != null) {

            String desc= element.getAttribute(DESCRIPTION);
            if (desc == null)
              desc= ""; //$NON-NLS-1$

            String autoInsert= element.getAttribute(AUTO_INSERT);
            boolean bAutoInsert;
            if (autoInsert == null)
              bAutoInsert= true;
            else
              bAutoInsert= Boolean.valueOf(autoInsert).booleanValue();

            Template template= new Template(name, desc, contextTypeId, pattern, bAutoInsert);
            TemplatePersistenceData data= new TemplatePersistenceData(template, true, id);
            if (validateTemplate(template))
              map.add(data);
          }
        }
      }
    }
  }

  private static boolean isValidTemplateId(String id) {
    return id != null && id.trim().length() != 0; // TODO test validity?
  }

  /*
   * @see org.eclipse.jface.text.templates.persistence.TemplateStore#handleException(java.io.IOException)
   * @since 3.2
   */
  protected void handleException(IOException x) {
    TextEditorPlugin.log(x);
  }
}
TOP

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

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.