Package org.eclipse.php.formatter.ui.preferences

Source Code of org.eclipse.php.formatter.ui.preferences.ProfileStore$ProfileDefaultHandler

/*******************************************************************************
* Copyright (c) 2013, 2014 Zend Techologies Ltd.
* 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:
*     Zend Technologies Ltd. - initial API and implementation
*******************************************************************************/

package org.eclipse.php.formatter.ui.preferences;

import java.io.*;
import java.util.*;

import javax.xml.parsers.*;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ProjectScope;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.eclipse.core.runtime.preferences.IScopeContext;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.php.formatter.core.FormatterCorePlugin;
import org.eclipse.php.formatter.ui.FormatterMessages;
import org.eclipse.php.formatter.ui.FormatterUIPlugin;
import org.eclipse.php.formatter.ui.Logger;
import org.eclipse.php.formatter.ui.preferences.ProfileManager.CustomProfile;
import org.eclipse.php.formatter.ui.preferences.ProfileManager.Profile;
import org.osgi.service.prefs.BackingStoreException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

public class ProfileStore {

  /**
   * A SAX event handler to parse the xml format for profiles.
   */
  private final static class ProfileDefaultHandler extends DefaultHandler {

    private List fProfiles;

    private String fName;
    private Map fSettings;

    public void startElement(String uri, String localName, String qName,
        Attributes attributes) throws SAXException {

      if (qName.equals(XML_NODE_SETTING)) {

        final String key = attributes.getValue(XML_ATTRIBUTE_ID);
        final String value = attributes.getValue(XML_ATTRIBUTE_VALUE);
        fSettings.put(key, value);

      } else if (qName.equals(XML_NODE_PROFILE)) {

        fName = attributes.getValue(XML_ATTRIBUTE_NAME);
        fSettings = new HashMap(200);

      } else if (qName.equals(XML_NODE_ROOT)) {
        fProfiles = new ArrayList();
      }
    }

    public void endElement(String uri, String localName, String qName) {
      if (qName.equals(XML_NODE_PROFILE)) {
        fProfiles.add(new CustomProfile(fName, fSettings));
        fName = null;
        fSettings = null;
      }
    }

    public List getProfiles() {
      return fProfiles;
    }

  }

  /**
   * Preference key where all profiles are stored
   */
  private static final String PREF_FORMATTER_PROFILES = "org.eclipse.php.ui.formatterprofiles"; //$NON-NLS-1$

  /**
   * Identifiers for the XML file.
   */
  private final static String XML_NODE_ROOT = "profiles"; //$NON-NLS-1$
  private final static String XML_NODE_PROFILE = "profile"; //$NON-NLS-1$
  private final static String XML_NODE_SETTING = "setting"; //$NON-NLS-1$

  private final static String XML_ATTRIBUTE_ID = "id"; //$NON-NLS-1$
  private final static String XML_ATTRIBUTE_NAME = "name"; //$NON-NLS-1$
  private final static String XML_ATTRIBUTE_VALUE = "value"; //$NON-NLS-1$

  private ProfileStore() {
  }

  /**
   * @return Returns the collection of profiles currently stored in the
   *         preference store or <code>null</code> if the loading failed. The
   *         elements are of type {@link CustomProfile} and are all updated to
   *         the latest version.
   * @throws CoreException
   */
  public static List readProfiles(IScopeContext scope) throws CoreException {
    List res = readProfilesFromPreferences(scope);
    if (res == null) {
      return readOldForCompatibility(scope);
    }
    return res;
  }

  public static void writeProfiles(Collection profiles,
      IScopeContext instanceScope) throws CoreException {
    ByteArrayOutputStream stream = new ByteArrayOutputStream(2000);
    try {
      writeProfilesToStream(profiles, stream);
      String val;
      try {
        val = stream.toString("UTF-8"); //$NON-NLS-1$
      } catch (UnsupportedEncodingException e) {
        val = stream.toString();
      }
      IEclipsePreferences uiPreferences = instanceScope
          .getNode(FormatterCorePlugin.PLUGIN_ID);
      uiPreferences.put(PREF_FORMATTER_PROFILES, val);
      uiPreferences.flush();
    } catch (BackingStoreException e) { /* ignore */
    } finally {
      try {
        stream.close();
      } catch (IOException e) { /* ignore */
      }
    }
  }

  public static List readProfilesFromPreferences(IScopeContext scope)
      throws CoreException {
    String string = scope.getNode(FormatterCorePlugin.PLUGIN_ID).get(
        PREF_FORMATTER_PROFILES, null);
    if (string != null && string.length() > 0) {
      byte[] bytes;
      try {
        bytes = string.getBytes("UTF-8"); //$NON-NLS-1$
      } catch (UnsupportedEncodingException e) {
        bytes = string.getBytes();
      }
      InputStream is = new ByteArrayInputStream(bytes);
      try {
        List res = readProfilesFromStream(new InputSource(is));
        return res;
      } finally {
        try {
          is.close();
        } catch (IOException e) { /* ignore */
        }
      }
    }
    return null;
  }

  /**
   * Read the available profiles from the internal XML file and return them as
   * collection.
   *
   * @return returns a list of <code>CustomProfile</code> or <code>null</code>
   */
  private static List readOldForCompatibility(IScopeContext instanceScope) {

    // in 3.0 M9 and less the profiles were stored in a file in the plugin's
    // meta data
    final String STORE_FILE = "code_formatter_profiles.xml"; //$NON-NLS-1$

    File file = FormatterUIPlugin.getDefault().getStateLocation()
        .append(STORE_FILE).toFile();
    if (!file.exists())
      return null;

    try {
      // note that it's wrong to use a file reader when XML declares
      // UTF-8: Kept for compatibility
      final FileReader reader = new FileReader(file);
      try {
        List res = readProfilesFromStream(new InputSource(reader));
        if (res != null) {
          writeProfiles(res, instanceScope);
        }
        file.delete(); // remove after successful write
        return res;
      } finally {
        reader.close();
      }
    } catch (CoreException e) {
      Logger.logException(e);// log but ignore
    } catch (IOException e) {
      Logger.logException(e); // log but ignore
    }
    return null;
  }

  /**
   * Read the available profiles from the internal XML file and return them as
   * collection or <code>null</code> if the file is not a profile file.
   *
   * @param file
   *            The file to read from
   * @return returns a list of <code>CustomProfile</code> or <code>null</code>
   * @throws CoreException
   */
  public static List readProfilesFromFile(File file) throws CoreException {
    try {
      final FileInputStream reader = new FileInputStream(file);
      try {
        return readProfilesFromStream(new InputSource(reader));
      } finally {
        try {
          reader.close();
        } catch (IOException e) { /* ignore */
        }
      }
    } catch (IOException e) {
      throw createException(
          e,
          FormatterMessages.CodingStyleConfigurationBlock_error_reading_xml_message);
    }
  }

  /**
   * Load profiles from a XML stream and add them to a map or
   * <code>null</code> if the source is not a profile store.
   *
   * @param inputSource
   *            The input stream
   * @return returns a list of <code>CustomProfile</code> or <code>null</code>
   * @throws CoreException
   */
  private static List readProfilesFromStream(InputSource inputSource)
      throws CoreException {

    final ProfileDefaultHandler handler = new ProfileDefaultHandler();
    try {
      final SAXParserFactory factory = SAXParserFactory.newInstance();
      final SAXParser parser = factory.newSAXParser();
      parser.parse(inputSource, handler);
    } catch (SAXException e) {
      throw createException(
          e,
          FormatterMessages.CodingStyleConfigurationBlock_error_reading_xml_message);
    } catch (IOException e) {
      throw createException(
          e,
          FormatterMessages.CodingStyleConfigurationBlock_error_reading_xml_message);
    } catch (ParserConfigurationException e) {
      throw createException(
          e,
          FormatterMessages.CodingStyleConfigurationBlock_error_reading_xml_message);
    }
    return handler.getProfiles();
  }

  /**
   * Write the available profiles to the internal XML file.
   *
   * @param profiles
   *            List of <code>CustomProfile</code>
   * @param file
   *            File to write
   * @throws CoreException
   */
  public static void writeProfilesToFile(Collection profiles, File file)
      throws CoreException {
    final OutputStream writer;
    try {
      writer = new FileOutputStream(file);
      try {
        writeProfilesToStream(profiles, writer);
      } finally {
        try {
          writer.close();
        } catch (IOException e) { /* ignore */
        }
      }
    } catch (IOException e) {
      throw createException(
          e,
          FormatterMessages.CodingStyleConfigurationBlock_error_serializing_xml_message);
    }
  }

  /**
   * Save profiles to an XML stream
   *
   * @param profiles
   *            List of <code>CustomProfile</code>
   * @param stream
   *            Stream to write
   * @throws CoreException
   */
  private static void writeProfilesToStream(Collection profiles,
      OutputStream stream) throws CoreException {

    try {
      final DocumentBuilderFactory factory = DocumentBuilderFactory
          .newInstance();
      final DocumentBuilder builder = factory.newDocumentBuilder();
      final Document document = builder.newDocument();

      final Element rootElement = document.createElement(XML_NODE_ROOT);

      document.appendChild(rootElement);

      for (final Iterator iter = profiles.iterator(); iter.hasNext();) {
        final Profile profile = (Profile) iter.next();
        if (profile.isProfileToSave()) {
          final Element profileElement = createProfileElement(
              profile, document);
          rootElement.appendChild(profileElement);
        }
      }

      Transformer transformer = TransformerFactory.newInstance()
          .newTransformer();
      transformer.setOutputProperty(OutputKeys.METHOD, "xml"); //$NON-NLS-1$
      transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); //$NON-NLS-1$
      transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$
      transformer.transform(new DOMSource(document), new StreamResult(
          stream));
    } catch (TransformerException e) {
      throw createException(
          e,
          FormatterMessages.CodingStyleConfigurationBlock_error_serializing_xml_message);
    } catch (ParserConfigurationException e) {
      throw createException(
          e,
          FormatterMessages.CodingStyleConfigurationBlock_error_serializing_xml_message);
    }
  }

  /*
   * Create a new profile element in the specified document. The profile is
   * not added to the document by this method.
   */
  private static Element createProfileElement(Profile profile,
      Document document) {
    final Element element = document.createElement(XML_NODE_PROFILE);
    element.setAttribute(XML_ATTRIBUTE_NAME, profile.getName());

    final Iterator keyIter = ProfileManager.getKeys().iterator();

    while (keyIter.hasNext()) {
      final String key = (String) keyIter.next();
      final String value = (String) profile.getSettings().get(key);
      if (value != null) {
        final Element setting = document
            .createElement(XML_NODE_SETTING);
        setting.setAttribute(XML_ATTRIBUTE_ID, key);
        setting.setAttribute(XML_ATTRIBUTE_VALUE, value);
        element.appendChild(setting);
      } else {
        Logger.log(
            Logger.ERROR,
            "ProfileStore: Profile does not contain value for key " + key); //$NON-NLS-1$
      }
    }
    return element;
  }

  public static void checkCurrentOptionsVersion() {
    IScopeContext instanceScope = InstanceScope.INSTANCE;
    try {
      List profiles = ProfileStore.readProfiles(instanceScope);
      if (profiles == null) {
        profiles = Collections.EMPTY_LIST;
      }
      ProfileManager manager = new ProfileManager(profiles, instanceScope);
      if (manager.getSelected() instanceof CustomProfile) {
        manager.commitChanges(instanceScope); // updates JavaCore
                            // options
      }
      savePreferences(instanceScope);

      IProject[] projects = ResourcesPlugin.getWorkspace().getRoot()
          .getProjects();
      for (int i = 0; i < projects.length; i++) {
        IScopeContext scope = new ProjectScope(projects[i]);
        if (ProfileManager.hasProjectSpecificSettings(scope)) {
          manager = new ProfileManager(profiles, scope);
          manager.commitChanges(scope); // updates JavaCore project
                          // options
          savePreferences(scope);
        }
      }
    } catch (CoreException e) {
      Logger.logException(e);
    } catch (BackingStoreException e) {
      Logger.logException(e);
    }
  }

  private static void savePreferences(final IScopeContext context)
      throws BackingStoreException {
    context.getNode(FormatterCorePlugin.PLUGIN_ID).flush();
  }

  /*
   * Creates a UI exception for logging purposes
   */
  private static CoreException createException(Throwable t, String message) {
    return new CoreException(new Status(IStatus.ERROR,
        FormatterUIPlugin.PLUGIN_ID, IStatus.ERROR, message, t));
  }
}
TOP

Related Classes of org.eclipse.php.formatter.ui.preferences.ProfileStore$ProfileDefaultHandler

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.