Package org.eclipse.ui.internal.cheatsheets.composite.parser

Source Code of org.eclipse.ui.internal.cheatsheets.composite.parser.CompositeCheatSheetParser

/*******************************************************************************
* Copyright (c) 2005, 2006 IBM Corporation 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:
*     IBM Corporation - initial API and implementation
*******************************************************************************/

package org.eclipse.ui.internal.cheatsheets.composite.parser;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.osgi.util.NLS;
import org.eclipse.ui.internal.cheatsheets.Messages;
import org.eclipse.ui.internal.cheatsheets.composite.model.AbstractTask;
import org.eclipse.ui.internal.cheatsheets.composite.model.CompositeCheatSheetModel;
import org.eclipse.ui.internal.cheatsheets.composite.model.EditableTask;
import org.eclipse.ui.internal.cheatsheets.composite.model.TaskGroup;
import org.eclipse.ui.internal.cheatsheets.data.CheatSheetParserException;
import org.eclipse.ui.internal.cheatsheets.data.IParserTags;
import org.eclipse.ui.internal.cheatsheets.data.ParserStatusUtility;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

public class CompositeCheatSheetParser implements IStatusContainer {
 
  private DocumentBuilder documentBuilder;
 
  private IStatus status;
 
  private int nextTaskId = 0;
 
 
  /**
   *  Gets the status of the last call to parseGuide
   */
 
  public IStatus getStatus() {
    return status;
  }
 
  /**
   * Returns the DocumentBuilder to be used by composite cheat sheets.
   */
  public DocumentBuilder getDocumentBuilder() {
    if(documentBuilder == null) {
      try {
        documentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
      } catch (Exception e) {
        addStatus(IStatus.ERROR, Messages.ERROR_CREATING_DOCUMENT_BUILDER, e);
      }
    }
    return documentBuilder;
  }
   
  public void addStatus(int severity, String message, Throwable exception) {
    status = ParserStatusUtility.addStatus(status, severity, message, exception);
  }
 
  /**
   * Parse a composite cheat sheet from a url. The parser status will be set as a result
   * of this operation, if the status is IStatus.ERROR the parser returns null 
   * @param url The url of the input
   * @return A valid composite cheat sheet or null if there was an error
   */
  public CompositeCheatSheetModel parseGuide(URL url) {
    status = Status.OK_STATUS;
    if(url == null) {
      String message = NLS.bind(Messages.ERROR_OPENING_FILE, (new Object[] {""})); //$NON-NLS-1$
      addStatus(IStatus.ERROR,  message,  null);
      return null;
    }

    InputStream is = null

    try {
      is = url.openStream();

      if (is == null) {
        String message = NLS.bind(Messages.ERROR_OPENING_FILE, (new Object[] {url.getFile()}));
        addStatus(IStatus.ERROR,  message,  null);
        return null;
      }
    } catch (Exception e) {
      String message = NLS.bind(Messages.ERROR_OPENING_FILE, (new Object[] {url.getFile()}));
      addStatus(IStatus.ERROR,  message,  e);
      return null;
    }
   
    Document document; 
    String filename = url.getFile();
    try {
      InputSource inputSource = new InputSource(is);
      document = getDocumentBuilder().parse(inputSource);
    } catch (IOException e) {
      String message = NLS.bind(Messages.ERROR_OPENING_FILE_IN_PARSER, (new Object[] {filename}));
      addStatus(IStatus.ERROR,  message,  e);
      return null;
    } catch (SAXParseException spe) {
      String message = NLS.bind(Messages.ERROR_SAX_PARSING_WITH_LOCATION, (new Object[] {filename, new Integer(spe.getLineNumber()), new Integer(spe.getColumnNumber())}));
      addStatus(IStatus.ERROR,  message,  spe);
      return null;
    } catch (SAXException se) {
      String message = NLS.bind(Messages.ERROR_SAX_PARSING, (new Object[] {filename}));
      addStatus(IStatus.ERROR,  message, se);
      return null;
    } finally {
      try {
        is.close();
      } catch (Exception e) {
      }
    }
   
    CompositeCheatSheetModel result = parseCompositeCheatSheet(document, url);
    return result;   
  }

  /**
   * Parse a composite cheatsheet. The parser status will be set as a result
   * of this operation, if the status is IStatus.ERROR the parser returns null 
   * @param url The url of the input. This is only used so the model can record
   * its input location
   * @param document the document to be parse
   * @return A valid composite cheat sheet or null if there was an error
   * @return
   */
  public CompositeCheatSheetModel parseCompositeCheatSheet(Document document, URL url)   {
    status = Status.OK_STATUS;
    try {
      // If the document passed is null return a null tree and update the status
      if (document != null) {
        Node rootnode = document.getDocumentElement();
       
        // Is the root node correct?
        if( !rootnode.getNodeName().equals(ICompositeCheatsheetTags.COMPOSITE_CHEATSHEET )) {
          String message = NLS.bind(Messages.ERROR_PARSING_ROOT_NODE_TYPE, (
              new Object[] {ICompositeCheatsheetTags.COMPOSITE_CHEATSHEET}));
          throw new CheatSheetParserException(message);
        }
       
        String name = ""//$NON-NLS-1$
        boolean nameFound = false;
        String explorerId = ICompositeCheatsheetTags.TREE;
       
        NamedNodeMap attributes = rootnode.getAttributes();
        if (attributes != null) {
          for (int x = 0; x < attributes.getLength(); x++) {
            Node attribute = attributes.item(x);
            String attributeName = attribute.getNodeName();
            if ( attributeName != null && attributeName.equals(ICompositeCheatsheetTags.NAME)) {
              nameFound = true;
              name= attribute.getNodeValue();
            }
            if (attributeName.equals(ICompositeCheatsheetTags.EXPLORER)) {
              explorerId= attribute.getNodeValue();
            }
          }
        }
        CompositeCheatSheetModel compositeCS = new CompositeCheatSheetModel(name, name, explorerId);
       
        parseCompositeCheatSheetChildren(rootnode, compositeCS);
       
        compositeCS.getDependencies().resolveDependencies(this);
       
        if (compositeCS.getRootTask() == null) {
          addStatus(IStatus.ERROR, Messages.ERROR_PARSING_NO_ROOT, null);
        }
        if (!nameFound) {
          addStatus(IStatus.ERROR, Messages.ERROR_PARSING_CCS_NO_NAME, null);
        }
        if (status.getSeverity() != IStatus.ERROR) {
          compositeCS.setContentUrl(url);
            return compositeCS;
        }
      }
      return null;
    } catch(CheatSheetParserException e) {
      addStatus(IStatus.ERROR, e.getMessage(), null);
      return null;
   
  }

  private void parseCompositeCheatSheetChildren(Node compositeCSNode, CompositeCheatSheetModel model) {
    nextTaskId = 0;
    NodeList childNodes = compositeCSNode.getChildNodes();
    for (int index = 0; index < childNodes.getLength(); index++) {
      Node nextNode = childNodes.item(index);
      if (isAbstractTask(nextNode.getNodeName()) ) {
        AbstractTask task = parseAbstractTask(nextNode, model);
          if (model.getRootTask() == null ) {
          model.setRootTask(task);
          parseTaskChildren(nextNode, task, model);
          } else {
            addStatus(IStatus.ERROR, Messages.ERROR_PARSING_MULTIPLE_ROOT, null);
          }
      }
    }   
  }

  public static boolean isAbstractTask(String nodeName) {
    return nodeName == ICompositeCheatsheetTags.TASK ||
      nodeName == ICompositeCheatsheetTags.TASK_GROUP;
  }
 
  private void parseTaskChildren(Node parentNode, AbstractTask parentTask, CompositeCheatSheetModel model) {
    NodeList childNodes = parentNode.getChildNodes();
    ITaskParseStrategy strategy = parentTask.getParserStrategy();
    strategy.init();
    for (int index = 0; index < childNodes.getLength(); index++) {
      Node childNode = childNodes.item(index);
      if (childNode.getNodeType() == Node.ELEMENT_NODE) {
        String nodeName = childNode.getNodeName();
        if (nodeName == IParserTags.PARAM) {
          addParameter(parentTask, childNode.getAttributes());     
        } else if (nodeName == IParserTags.INTRO) {
          parentTask.setDescription(MarkupParser.parseAndTrimTextMarkup(childNode));
        } else if (nodeName == ICompositeCheatsheetTags.ON_COMPLETION) {
          parentTask.setCompletionMessage(MarkupParser.parseAndTrimTextMarkup(childNode));           
        } else if (nodeName == ICompositeCheatsheetTags.DEPENDS_ON) {
          parseDependency(childNode, parentTask, model);
        } else if (CompositeCheatSheetParser.isAbstractTask(nodeName)) {
          if (parentTask instanceof TaskGroup) {
              AbstractTask task = parseAbstractTask(childNode, model);
              ((TaskGroup)parentTask).addSubtask(task);
              parseTaskChildren(childNode, task, model);
          }
          } else {
          if (!strategy.parseElementNode(childNode, parentNode, parentTask, this)) {
            String message = NLS
            .bind(
                Messages.WARNING_PARSING_UNKNOWN_ELEMENT,
                (new Object[] { nodeName,
                    parentNode.getNodeName() }));
                addStatus(IStatus.WARNING, message, null);
          }
        }
      }
    } 
    // Check for missing attributes and add dependencies if this was a sequence
    strategy.parsingComplete(parentTask, this);
  }

  private void parseDependency(Node taskNode, AbstractTask task, CompositeCheatSheetModel model) {
    NamedNodeMap attributes = taskNode.getAttributes();
    if (attributes != null) {
         Node taskAttribute = attributes.getNamedItem(ICompositeCheatsheetTags.TASK);
         if (taskAttribute != null) {
           String requiredTaskId = taskAttribute.getNodeValue();
           model.getDependencies().addDependency(task, requiredTaskId);
         } else {
           addStatus(IStatus.ERROR, Messages.ERROR_PARSING_NO_ID, null);
         }
    } 
  }

  private void addParameter(AbstractTask parentTask, NamedNodeMap attributes) {
    String name = null;
    String value = null;

    if (attributes != null) {
      for (int x = 0; x < attributes.getLength(); x++) {
        Node attribute = attributes.item(x);
        String attributeName = attribute.getNodeName();
        if (attribute == null || attributeName == null)
          continue;
        if (attributeName.equals(ICompositeCheatsheetTags.NAME)) {
          name = attribute.getNodeValue();
        }
        if (attributeName.equals(ICompositeCheatsheetTags.VALUE)) {
          value= attribute.getNodeValue();
       
      }
    }
    if (name == null) {
      addStatus(IStatus.WARNING, Messages.ERROR_PARSING_NO_NAME, null);
      return;
    } else if (value == null) {
      addStatus(IStatus.WARNING, Messages.ERROR_PARSING_NO_VALUE, null);
      return;
    } else {
      parentTask.getParameters().put(name, value);
    }
   
  }

  private AbstractTask parseAbstractTask(Node taskNode, CompositeCheatSheetModel model) {
    AbstractTask task;
    NamedNodeMap attributes = taskNode.getAttributes();
    String kind = null;
    String name = null;
    String id = null;
    boolean skippable = false;
    if (attributes != null) {
      for (int x = 0; x < attributes.getLength(); x++) {
        Node attribute = attributes.item(x);
        String attributeName = attribute.getNodeName();
        if (attribute == null || attributeName == null)
          continue;
        if (attributeName.equals(ICompositeCheatsheetTags.KIND)) {
          kind = attribute.getNodeValue();
        }
        if (attributeName.equals(ICompositeCheatsheetTags.NAME)) {
          name= attribute.getNodeValue();
        }
        if (attributeName.equals(IParserTags.ID)) {
          id = attribute.getNodeValue();
        }     
        if (attributeName.equals(IParserTags.SKIP)) {
          skippable = "true".equalsIgnoreCase(attribute.getNodeValue()); //$NON-NLS-1$
        }       
      }
    }

    String nodeName = taskNode.getNodeName();
    if (id == null) {
      id = autoGenerateId();
    }
    if (name == null) {
      String message = NLS.bind(Messages.ERROR_PARSING_TASK_NO_NAME, (new Object[] {nodeName}));
      addStatus(IStatus.ERROR, message, null);
    }
    task = createTask(nodeName, model, kind, id, name);
    task.setSkippable(skippable);

    if (model.getDependencies().getTask(id) != null) {
      String message = NLS.bind(Messages.ERROR_PARSING_DUPLICATE_TASK_ID, (new Object[] {id, }));
      addStatus(IStatus.ERROR, message, null);
    } else {
        model.getDependencies().saveId(task);
    }

    return task;
  }

  private AbstractTask createTask(String nodeKind, CompositeCheatSheetModel model, String kind, String id, String name) {
    AbstractTask task;
    if (ICompositeCheatsheetTags.TASK_GROUP.equals(nodeKind)) {
      task = new TaskGroup(model, id, name, kind);
    } else {
      task = new EditableTask(model, id, name, kind);
    }
    task.setCompletionMessage(Messages.COMPLETED_TASK);
    return task;
  }
 
  private String autoGenerateId() {
    return "TaskId_" + nextTaskId++; //$NON-NLS-1$
  }

}
TOP

Related Classes of org.eclipse.ui.internal.cheatsheets.composite.parser.CompositeCheatSheetParser

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.